一.CORS
1.同源政策
如果兩個頁面的協定,域名和端口完全一緻,則兩個頁面同源。
同源政策是浏覽器的一個安全功能,不同源的用戶端腳本(ajax)在沒有明确授權的情況下,不能讀寫對方資源。
2.CORS概念
CORS是一個W3C标準,全稱是"跨域資源共享"(Cross-origin resource sharing),是跨域問題的解決方案之一。它允許浏覽器向跨源伺服器,發出XMLHttpRequest請求,進而克服了AJAX隻能同源使用的限制。
3.CORS特點
- 浏覽器自動完成(在請求頭中加入特殊頭 或 發送特殊請求)
- 伺服器需要支援(響應頭中需要有特殊頭)
4.跨域請求類型
- 簡單請求
- 請求方法如下:GET or HEAD or POST
- 請求頭僅包含:Accept,Accept-Language,Content-Language,Content-Type
- Content-Type 僅支援如下三種:application/x-www-form-urlencoded,multipart/form-data,ext/plain
2.預檢請求:不滿足以上任意一點的請求都是 預檢請求
前後端分離時通過json傳輸資料,是以content_type必然不滿足簡單請求的要求(application/json),是以均為預檢請求
5.跨域請求流程
-
簡單請求流程
請求頭中 攜帶 Origin,該字段表明自己來自哪個域
如果請求頭中的Origin在伺服器接受範圍内, 則傳回如下頭:
如果伺服器不接受此域,則響應頭中不包含 Access-Control-Allow-Origin
響應頭 | 作用 | 備注 |
---|---|---|
Access-Control-Allow-Origin | 伺服器接受的域 | |
Access-Control-Allow-Credentials | 是否接受跨域的Cooike | 可選 |
Access-Control-Expose-Headers | 預設情況下,xhr隻能拿到如下響應頭:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified;如果有需要擷取其他頭,需在此指定 | 可選 |
- 預檢請求流程:使用設定的請求方式請求資料之前,先發送一個OPTIONS請求,看服務端是否允許用戶端發送非簡單請求,隻有"預檢"通過後才會再發送一次請求用于資料傳輸
- OPTION 請求發起,攜帶如下請求頭
請求頭 | 作用 | 備注 |
---|---|---|
Origin | 表明此請求來自哪個域 | 必選 |
Access-Control-Request-Method | 此次請求使用方法 | 必選 |
Access-Control-Request-Headers | 此次請求使用的頭 | 必選 |
- OPTION 接受響應階段,攜帶如下響應頭
響應頭 | 作用 | 備注 |
---|---|---|
Access-Control-Allow-Origin | 同簡單請求 | 必選 |
Access-Control-Allow-Methods | 告訴浏覽器,伺服器接受得跨域請求方法 | 必選 |
Access-Control-Allow-Headers | 傳回所有支援的頭部,當request有 ‘Access-Control-Request-Headers’時,該響應頭必然回複 | 必選 |
Access-Control-Allow-Credentials | 同簡單請求 | 可選 |
Access-Control-Max-Age | OPTION請求緩存時間,機關s 每次預檢請求都會發送OPTION和post兩個請求,此設定可緩解伺服器壓力 | 可選 |
- 主請求階段
請求頭 | 作用 | 備注 |
---|---|---|
Origin | 表明此請求來自哪個域 |
- 主請求響應階段
響應頭 | 作用 | 備注 |
---|---|---|
Access-Control-Allow-Origin | 目前伺服器接受得域 |
二.django對CORS的支援
pip install django-cors-headers
settings.py中增加如下配置
1,INSTALLED_APPS 中添加 corsheaders
2,MIDDLEWARE 中添加 corsheaders.middleware.CorsMiddleware
位置盡量靠前,官方建議放在 ‘django.middleware.common.CommonMiddleware’ 上方
禁掉csrf中間件
3,CORS_ORIGIN_ALLOW_ALL 布爾值 如果為True,所有域均可通路 白名單不啟用
4,CORS_ORIGIN_WHITELIST =[
"https://example.com"
]
5, CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
6, CORS_ALLOW_HEADERS = (
'accept-encoding',
'authorization', # 這個裡面放token
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
7, CORS_PREFLIGHT_MAX_AGE 浏覽器或者用戶端可以緩存預檢響應的秒數,
如果是0或者任何假值,則再次發送請求時,還需要進行預檢,預設是86400(一天)
8, CORS_EXPOSE_HEADERS [] 擴充的請求頭,預設為空
9, CORS_ALLOW_CREDENTIALS 是否接收cookie,布爾值, 預設False