服務器的同源策略:html
爲了安全性瀏覽器有一個同源策略, 一個域名下的應用使用許多數據或者請求的獲取, 被限制在同一域名, 協議, 端口, 否則瀏覽器不會容許請求這些資源, 直接請求就發不出去。前端
同源的3種行爲:nginx
(1) Cookie、LocalStorage 和 IndexDB 沒法讀取。後端
(2) DOM 沒法得到。api
(3) AJAX 請求不能發送。 跨域
可是隨着互聯網的發展, 咱們確實須要資源或者服務分佈到不一樣的域當中, 好比先後端分離後, 前端應用和後端的API服務器可能就處於不一樣的域下。瀏覽器
要跨域去獲取數據有3中方法: JSONP, WebSocket, CORS。 這裏主要講CORS的使用與配置。安全
CORS 使用簡介:服務器
爲了知足新時期的需求, W3C擬定了新的標準, "跨域資源共享"(Cross-origin resource sharing)來使得咱們能夠實現跨域訪問。這裏須要注意的是, 這個新的協議徹底是由 瀏覽器 和 服務端 來決定的, 而對於前端開發者來講是徹底隱藏了細節的, 前端開發者這裏不須要增長任何額外的工做, 瀏覽器會自動的識別請求是不是跨域請求, 從而與服務端完成通訊, 因此只須要後端開發者正確的設置後。
app
CORS 類型與通訊過程:
瀏覽器會將CORS請求分紅2類: 簡單請求 和 非簡單請求。對於非簡單請求, 瀏覽器會在正式發出請求前, 多發送一次
"預檢"請求( preflight )用於詢問服務端是否容許非簡單請求, 若是服務端容許, 瀏覽器纔會發送請求過去。
1) 請求方法是如下三種方法之一:
(2)HTTP的頭信息不超出如下幾種字段:
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
認爲知足以上2條的就是簡單請求, 之外都是非簡單請求。
服務端利用一下3個請求頭來控制此次請求是否合法:
Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8
每個跨域請求都會被瀏覽器自動添加一個
Origin: http://api.bob.com
請求頭用來代表本身的origin域是哪裏, 而後服務端就能夠根據這個 origin 來判斷是否容許請求。
對應的服務端若是容許這個請求, 那麼必須添加
Access-Control-Allow-Origin: *
( 不必定是 * 可是必須包括請求的origin域 )
請求頭來代表本身接受了這個請求, 否則就算成功返回了數據, 瀏覽器同樣會報錯:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
No 'Access-Control-Allow-Origin' header is present on the requested resource。
並且返回的 code 可能任然是200。
後臺如何配置:
後臺配置須要配置好這3個頭: Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Expose-Headers 就能正常的完成HTTP的跨域通訊了。
這裏附上nginx的配置:
server{ listen 2000; server_name api_server; root path_to_app; charset utf8; location / { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'POST, GET, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; if ($request_method = 'OPTIONS') { return 204; } } }
這裏的配置很是簡單粗暴, 具體請根據需求來設置。
參考資料:
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
http://www.ruanyifeng.com/blog/2016/04/cors.html