一:

  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这个地址的请求。
那么:
我们是得不到数据的?
为什么得不到数据呢?
原因:浏览器不要这个数据
django之csrf_exempt解决跨域请求的问题
理解:跨域不是服务器不给数据,也不是浏览器发现了跨域,不进行了请求。

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

 例子:

服务器
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>

# 前端运行
django之csrf_exempt解决跨域请求的问题

 

 解决:服务器响应的时候,给请求头加入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端口运行的结果

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


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

结论:服务器通过响应头设置:跨域浏览器的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'),
]