• django之csrf_exempt解决跨域请求的问题


    一:

      from django.views.decorators.csrf import csrf_exempt
    # 获取微信返回的code信息
    @csrf_exempt
    def wechat_auth(req):
        if req.method == 'POST':
            code = req.POST.get('code')
            data_info = get_access_token_info(code)
            return JsonResponse({'message': data_info, "status": '1'})
        return JsonResponse({'message': '扫码失败,请刷新重试!',"status": 0})

      scrf_exempt是用来解决视图可以进行跨域请求。

      1:什么是跨域请求呢?

    假如:
    在http:www.aa:8080/index.html里面的js代码发起了http:api:aa:9999/index_data这个地址的请求。
    那么:
    我们是得不到数据的?
    为什么得不到数据呢?
    原因:浏览器不要这个数据

    理解:跨域不是服务器不给数据,也不是浏览器发现了跨域,不进行了请求。

    解决:同源策略是浏览器的策略,和服务器没有关系,不过我们可以通过对服务器的响应头配置,让浏览器接收这次数据(后端解决办法)

     例子:

    服务器
    from
    flask import Flask from flask import make_response from flask import render_template app = Flask(__name__) # 服务器代码 @app.route("/index_data", methods=["GET"]) def test1(): print("服务器接收了这次请求") response = make_response("hello world") return response if __name__ == '__main__': app.run(debug=True,host="0.0.0.0",port=9999)

    # 端口为9999的服务器
    # 后端
    from flask import Flask
    from flask import render_template
    app = Flask(__name__)
    @app.route("/index", methods=["GET"])
    def test1():
        return render_template("csrf_test.html")
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    # 前端
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/jquery-1.12.4.min.js"></script>
        <script>
            $(function () {
                $("#btn").click(function () {
    
                    $.ajax({"
                        url:"http://127.0.0.1:9999/index_data",  #从 http:127.0.0.1:5000/index的域向http:127.0.0.1:9999/index_data的域发送请求
                        type:"get",
                        success:function (dat) {
                            console.log(dat)
                        }
                    })
                })
            })
        </script>
    </head>
    <body>
    <input type="submit" value="点我试试" id="btn">
    </body>
    </html>
    
    # 前端运行

     解决:服务器响应的时候,给请求头加入Acess-Control-Allow-Origin参数:值为:http://127.0.0.1:5000 就可以解决从5000端口向9999端口要数据的情况。

    from flask import Flask
    from flask import make_response
    from flask import render_template
    
    app = Flask(__name__)
    
    # 服务器代码
    @app.route("/index_data", methods=["GET"])
    def test1():
        print("服务器接收了这次请求")
        response = make_response("hello world")
        response.headers["Access-Control-Allow-Origin"] = "http://127.0.0.1:5000"  # 服务器告诉浏览器,允许5000端口进行数据传输。
        return response
    
    if __name__ == '__main__':
        app.run(debug=True,host="0.0.0.0",port=9999)

    5000端口运行的结果
    
    

    同源策略:同协议、同域名、同端口

    结论:服务器通过响应头设置:跨域浏览器的host:port,保证跨域浏览器的能够顺利的拿到服务器的数据。

     二:浏览器的请求头中

       更复杂的跨区请求:浏览器还会先发送options请求,然后在发送正常的get请求,因此还要对response.headers中添加更过的字段

      # TODO 后面会进行测试。

     三:django中的跨域请求的解决方法

      方法一:普通的视图函数

    # 获取微信返回的code信息
    @csrf_exempt
    def wechat_auth(req):
        if req.method == 'POST':
            code = req.POST.get('code')
            data_info = get_access_token_info(code)
            return JsonResponse({'message': data_info, "status": '1'})
        return JsonResponse({'message': '扫码失败,请刷新重试!',"status": 0})

      方法二:继承视图类的类视图

    from django.views.decorators.csrf import csrf_exempt
    
    class MyView(View):
    
        def get(self, request):
            return HttpResponse("hi")
    
        def post(self, request):
            return HttpResponse("hi")
    
        @csrf_exempt
        def dispatch(self, *args, **kwargs):
            return super(MyView, self).dispatch(*args, **kwargs)

      方法三:在urls.py中设置

    from django.conf.urls import url
    from django.views.decorators.csrf import csrf_exempt
    import views
    
    urlpatterns = [
        url(r'^myview/$', csrf_exempt(views.MyView.as_view()), name='myview'),
    ]
  • 相关阅读:
    多个数字和数字字符串混合运算规则
    关于js对象引用的小例子
    实现函数 isInteger(x) 来判断 x 是否是整数
    写一个少于 80 字符的函数,判断一个字符串是不是回文字符串
    关于数组排序
    事件委托(事件代理)的原理以及优缺点是什么?
    将url的查询参数解析成字典对象
    js dom操作获取节点的一些方法
    js中arguments的应用
    深度克隆---js对象引用
  • 原文地址:https://www.cnblogs.com/meloncodezhang/p/11752602.html
Copyright © 2020-2023  润新知