若是兩個頁面的協議,端口和域名都相同,則兩個頁面具備相同的源。前端
若是有其中一個不一樣,就會被瀏覽器的同源策略阻止。ios
同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,若是缺乏了同源策略,則瀏覽器的正常功能可能都會受到影響。 能夠說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。git
1. 頁面中的連接,重定向以及表單提交是不會受到同源策略限制的。github
2. 跨域資源的引入是能夠的。可是js不能讀寫加載的內容。如嵌入到頁面中的<script src="..."></script>,<img>,<link>,<iframe>等。ajax
同源策略限制跨域發送ajax請求。django
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它容許瀏覽器向跨源服務器發出XMLHttpRequest請求,從而解決AJAX只能同源使用的限制。json
CORS須要瀏覽器和服務器同時支持。目前基本上主流的瀏覽器都支持CORS。因此只要後端服務支持CORS,就可以實現跨域。axios
瀏覽器將CORS請求分紅兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。後端
一個請求須要同時知足如下兩大條件才屬於簡單請求。跨域
(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
解決簡單請求
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 預檢 請求。該請求會像後端服務詢問是否容許從當前源發送請求而且詢問容許的 請求方法 和 請求頭字段。
舉個例子:
咱們前端使用axios向後端發送PUT請求,結果:
解決辦法
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
咱們這個中間件確實能解決目前的CORS跨域問題,可是咱們的土方法確定是不夠嚴謹的,已經有人造好輪子-- django-cors-headers 了。
咱們只須要安裝這個包,而後按須要配置一下就能夠了。
pip install django-cors-headers
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項目