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