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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM