日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Django 【第二十篇】后端CORS解决跨域问题

發布時間:2023/12/18 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django 【第二十篇】后端CORS解决跨域问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、為什么會有跨域問題?

是因為瀏覽器的同源策略是對ajax請求進行阻攔了,但是不是所有的請求都給做跨域,像是一般的href屬性,a標簽什么的都不攔截。

?

二、解決跨域問題的兩種方式

  • JSONP
  • CORS?

?

三、JSONP

先簡單來說一下JSONP,具體詳細詳見上面JSONP

JSONP是json用來跨域的一個東西。原理是通過script標簽的跨域特性來繞過同源策略。(創建一個回調函數,然后在遠程服務上調用這個函數并且將json數據形式作為參數傳遞,完成回調)。

?

四、CORS跨域

隨著技術的發展,現在的瀏覽器可以主動支持設置從而允許跨域請求,即:跨域資源共享(CORS,Cross-Origin Resource Sharing),其本質是設置響應頭,使得瀏覽器允許跨域請求。

1、簡單請求和復雜請求

條件:1、請求方式:HEAD、GET、POST2、請求頭信息:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type 對應的值是以下三個中的任意一個application/x-www-form-urlencodedmultipart/form-datatext/plain注意:同時滿足以上兩個條件時,則是簡單請求,否則為復雜請求

2、簡單請求和復雜請求的區別?

簡單請求:一次請求

非簡單請求:兩次請求,在發送數據之前會先發第一次請求做‘預檢’,只有‘預檢’通過后才再發送一次請求用于數據傳輸。

3、關于預檢

- 請求方式:OPTIONS - “預檢”其實做檢查,檢查如果通過則允許傳輸數據,檢查不通過則不再發送真正想要發送的消息 - 如何“預檢”=> 如果復雜請求是PUT等請求,則服務端需要設置允許某請求,否則“預檢”不通過Access-Control-Request-Method=> 如果復雜請求設置了請求頭,則服務端需要設置允許某請求頭,否則“預檢”不通過Access-Control-Request-Headers

4、CORS的優缺點

  • CORS的優點:可以發任意請求
  • CORS的缺點:上是復雜請求的時候得先做個預檢,再發真實的請求。發了兩次請求會有性能上的損耗

?

五、JSONP和CORS的區別

JSONP:服務端不用修改,需要改前端。發jsonp請求

JSONP:只能發GET請求

CORS:前端的代碼不用修改,服務端的代碼需要修改。如果是簡單請求的話在服務端加上一個響應頭。

CORS:可以發任意請求

?

六、基于CORS實現ajax請求

1、支持跨域,簡單請求

客戶端

index.html

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width"><title>Title</title> </head> <body> <div><h1>歡迎來到我的主頁</h1><button οnclick="getData()">獲取用戶數據</button> </div> <script src="/static/jquery-1.12.4.min.js"></script> <script>function getData() {$.ajax({url:'http://127.0.0.1:8080/index/',type:"GET",success:function (data) {console.log(data)}})} </script> </body> </html>

  

服務端

views.py from django.shortcuts import render from django.http import JsonResponse from rest_framework.views import APIView# Create your views here. class IndexView(APIView):def get(self,request,*args,**kwargs):ret = {'code': 111,'data': '你好嗎?'}response = JsonResponse(ret)response['Access-Control-Allow-Origin'] = "*"return response

  

2、支持跨域,復雜請求

如果是復雜請求在你真正的發請求之前,會先偷偷的發一個OPTION請求,先預檢一下,我

允許你來你才來

如果想預檢通過就得寫個option請求

user.html <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width"><title>Title</title> </head> <body> <input type="button" value="獲取用戶數據" οnclick="getUser()"> <script src="/static/jquery-1.12.4.min.js"></script> <script>function getUser() {$.ajax({url:'http://127.0.0.1:8080/user/',type:'POST',data:{'k1':'v1'},headers:{'h1':'sdfdgfdg'},success:function (ret) {console.log(ret)}})} </script> </body> </html>user.html

  

服務端

from django.shortcuts import render,HttpResponse from django.http import JsonResponse from rest_framework.views import APIViewclass UserIndex(APIView):def get(self,request,*args,**kwargs):ret = {'code': 111,'data': '你好嗎?'}response = JsonResponse(ret)response['Access-Control-Allow-Origin'] = "*"return responsedef post(self,request,*args,**kwargs):print(request.POST.get('k1'))ret = {'code':1000,'data':'過年啦',}response = JsonResponse(ret)response['Access-Control-Allow-Origin'] = "*"return responsedef options(self, request, *args, **kwargs):# self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")# self.set_header('Access-Control-Allow-Headers', "k1,k2")# self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")# self.set_header('Access-Control-Max-Age', 10)response = HttpResponse()response['Access-Control-Allow-Origin'] = '*'response['Access-Control-Allow-Headers'] = 'h1'# response['Access-Control-Allow-Methods'] = 'PUT'return response

  

由于復雜請求時,首先會發送“預檢”請求,如果“預檢”成功,則發送真實數據。

  • “預檢”請求時,允許請求方式則需服務器設置響應頭:Access-Control-Request-Method
  • “預檢”請求時,允許請求頭則需服務器設置響應頭:Access-Control-Request-Headers
  • “預檢”緩存時間,服務器設置響應頭:Access-Control-Max-Age

3、跨域獲取響應頭

默認獲取到的所有響應頭只有基本信息,如果想要獲取自定義的響應頭,則需要再服務器端設置Access-Control-Expose-Headers。

a.html <!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8"><title></title> </head> <body><p><input type="submit" οnclick="XmlSendRequest();" /></p><p><input type="submit" οnclick="JqSendRequest();" /></p><script type="text/javascript" src="jquery-1.12.4.js"></script><script>function XmlSendRequest(){var xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){if(xhr.readyState == 4) {var result = xhr.responseText;console.log(result);// 獲取響應頭console.log(xhr.getAllResponseHeaders());}};xhr.open('PUT', "http://c2.com:8000/test/", true);xhr.setRequestHeader('k1', 'v1');xhr.send();}function JqSendRequest(){$.ajax({url: "http://c2.com:8000/test/",type: 'PUT',dataType: 'text',headers: {'k1': 'v1'},success: function(data, statusText, xmlHttpRequest){console.log(data);// 獲取響應頭console.log(xmlHttpRequest.getAllResponseHeaders());}})}</script> </body> </html>HTML

  

views.py class MainHandler(tornado.web.RequestHandler):def put(self):self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")self.set_header('xxoo', "seven")self.set_header('bili', "daobidao")self.set_header('Access-Control-Expose-Headers', "xxoo,bili")self.write('{"status": true, "data": "seven"}')def options(self, *args, **kwargs):self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")self.set_header('Access-Control-Allow-Headers', "k1,k2")self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")self.set_header('Access-Control-Max-Age', 10)

4、跨域傳輸cookie

在跨域請求中,默認情況下,HTTP Authentication信息,Cookie頭以及用戶的SSL證書無論在預檢請求中或是在實際請求都是不會被發送。

如果想要發送:

  • 瀏覽器端:XMLHttpRequest的withCredentials為true
  • 服務器端:Access-Control-Allow-Credentials為true
  • 注意:服務器端響應的?Access-Control-Allow-Origin 不能是通配符 *
b.html <!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8"><title></title> </head> <body><p><input type="submit" οnclick="XmlSendRequest();" /></p><p><input type="submit" οnclick="JqSendRequest();" /></p><script type="text/javascript" src="jquery-1.12.4.js"></script><script>function XmlSendRequest(){var xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){if(xhr.readyState == 4) {var result = xhr.responseText;console.log(result);}};xhr.withCredentials = true;xhr.open('PUT', "http://c2.com:8000/test/", true);xhr.setRequestHeader('k1', 'v1');xhr.send();}function JqSendRequest(){$.ajax({url: "http://c2.com:8000/test/",type: 'PUT',dataType: 'text',headers: {'k1': 'v1'},xhrFields:{withCredentials: true},success: function(data, statusText, xmlHttpRequest){console.log(data);}})}</script> </body> </html>HTML

  

views.py class MainHandler(tornado.web.RequestHandler):def put(self):self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")self.set_header('Access-Control-Allow-Credentials', "true")self.set_header('xxoo', "seven")self.set_header('bili', "daobidao")self.set_header('Access-Control-Expose-Headers', "xxoo,bili")self.set_cookie('kkkkk', 'vvvvv');self.write('{"status": true, "data": "seven"}')def options(self, *args, **kwargs):self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")self.set_header('Access-Control-Allow-Headers', "k1,k2")self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")self.set_header('Access-Control-Max-Age', 10)

  

?

?

?

轉載于:https://www.cnblogs.com/xiaohema/p/8456591.html

總結

以上是生活随笔為你收集整理的Django 【第二十篇】后端CORS解决跨域问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。