Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 814|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    6 天前
  • 签到天数: 803 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726482
    发表于 2021-4-12 14:29:25 | 显示全部楼层 |阅读模式

    一:

      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'),
    ]

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-23 20:19 , Processed in 0.122387 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表