一. jsonp解決跨域問題css
1. 函數中傳參html
dom1中的HTMLjquery
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>xyz</title> </head> <body> <button id="b1">點我</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> function rion(res) { console.log(res); } </script> <script src="http://127.0.0.1:8002/abc/"></script> </body> </html>
demo2 中的視圖函數:git
def abc(request): res = {"code": 0, "data": ["SNIS-561", "SNIS-517", "SNIS-539"]} return HttpResponse("rion({})".format(json.dumps(res)))
JQuery中getJSON方法:github
demo2中HTMLdjango
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>xyz</title> </head> <body> <button id="b1">點我</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> $("#b1").click(function () { $.getJSON("http://127.0.0.1:8002/abc/?callback=?", function (res) { console.log(res); }) }); </script> </body> </html>
要注意的是在url的後面必需要有一個callback參數,這樣getJSON方法纔會知道是用JSONP方式去訪問服務,callback後面的那個?是jQuery內部自動生成的一個回調函數名。json
二. CORS解決跨域問題後端
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它容許瀏覽器向跨源服務器發出XMLHttpRequest請求,從而解決AJAX只能同源使用的限制.跨域
瀏覽器將CORS請求分爲兩類: 簡單請求和非簡單請求瀏覽器
一個請求須要同時知足 如下兩大條件 才屬於簡單請求.
(1) 請求方法是如下三種方法之一: HEAD GET POST (2)HTTP的頭信息不超出如下幾種字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
簡單請求的處理方式
在跨域場景下,當瀏覽器發送簡單請求時,瀏覽器會自動在請求頭中添加代表請求來源的 Origin 字段。
咱們的後端程序只須要在返回的響應頭中加上 Access-Control-Allow-Origin 字段,而且把該字段的值設置爲 跨域請求的來源地址或簡單的設置爲 * 就能夠了。
例如:咱們能夠在Django中間件中的process_response方法來給相應對象添加該字段。
from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 給響應頭加上 Access-Control-Allow-Origin 字段 並簡單的設置爲 * response['Access-Control-Allow-Origin'] = '*' return response
非簡單請求的處理方式 >>
咱們開發中經常使用到的那些請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json的都是非簡單請求。
對於非簡單請求,瀏覽器一般都會在請求以前發送一次 OPTIONS 預檢 請求。該請求會像後端服務詢問是否容許從當前源發送請求而且詢問容許的 請求方法 和 請求頭字段。
解決方案在上面Django的中間件中添加以下代碼:
from django.utils.deprecation import MiddlewareMixin class CorsMiddleware(MiddlewareMixin): def process_response(self, request, response): # 給響應頭加上 Access-Control-Allow-Origin 字段 並簡單的設置爲 * response['Access-Control-Allow-Origin'] = '*' if request.method == 'OPTIONS': # 容許發送 PUT 請求 response['Access-Control-Allow-Methods'] = 'PUT, DELETE' # 容許在請求頭中攜帶 Content-type字段,從而支持發送json數據 response['Access-Control-Allow-Headers'] = 'Content-type' return response
三. 使用 Django-corset-headers 解決跨域問題
咱們這個中間件確實能解決目前的CORS跨域問題,可是咱們的土方法確定是不夠嚴謹的,已經有人造好輪子-- django-cors-headers 了。
咱們只須要安裝這個包,而後按須要配置一下就能夠了。
安裝
pip install django-cors-headers
註冊APP
INSTALLED_APPS = [ ... 'app01.apps.App01Config', 'corsheaders', # 將 corsheaders 這個APP註冊 ]
添加中間件
必須放在最前面,由於要先解決跨域的問題。只有容許跨域請求,後續的中間件纔會正常執行。
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 添加中間件 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
配置
你能夠選擇不限制跨域訪問
CORS_ORIGIN_ALLOW_ALL = True
或者你能夠選擇設置容許訪問的白名單
CORS_ORIGIN_ALLOW_ALL = False CORS_ORIGIN_WHITELIST = ( # '<YOUR_DOMAIN>[:PORT]', '127.0.0.1:8080' )
更多詳細配置詳細請查看django-cors-headers項目