首先通讀下 MDN 關於 CORS 的 定義,瞭解跨域的含義及簡單請求和複雜請求等的定義。文中的內容不贅述,如今說解決方案。webpack
經過定義咱們能夠,簡單請求與複雜請求的差異是複雜請求會自動發出一個 OPTIONS
的預檢請求,當請求獲得確認後,纔開始真正發送請求。web
綜上,咱們要解決兩個問題:shell
解決的方式有多種,既能夠在Web Server解決,也能夠在源碼層解決。由於問題比較廣泛,故咱們選擇在Web Server解決,下面咱們以 Nginx 爲例,說明解決方案。api
假設訪問的地址爲 /example
, Nginx 配置以下:跨域
location /example { proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080/; }
爲了解決跨域問題,添加以下內容:緩存
location /example { + if ($request_method = 'OPTIONS') { + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Max-Age 1728000; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; + add_header Content-Type' 'text/plain; charset=utf-8'; + add_header Content-Length 0 ; + return 204; + } proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080/; }
if ($request_method = 'OPTIONS') {...}
當請求方法爲 OPTIONS 時:
一、添加容許源 Access-Control-Allow-Origin
爲 * (可根據業務須要更改)
二、添加緩存時長 Access-Control-Max-Age
,當下次請求時,無需再發送 OPTIONS 請求
三、添加容許的方法,容許的首部
四、添加一個內容長度爲0,類型爲 text/plain; charset=utf-8
, 返回狀態碼爲 204
的首部
至此,完成 OPTIONS
請求的正確響應。webpack-dev-server
添加以下內容:ide
location /example { if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 1728000; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header Content-Type' 'text/plain; charset=utf-8'; add_header Content-Length 0 ; return 204; } + if ($http_origin ~* (https?://(.+\.)?(example\.com$))) { + add_header Access-Control-Allow-Origin $http_origin; + add_header Access-Control-Allow-Credentials true; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; + add_header Access-Control-Expose-Headers Content-Length,Content-Range; + } proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080/; }
if ($http_origin ~* (https?://(.+\.)?(example\.com$))) {...}
, 當 origin 爲合法域名(可根據業務調整或去除合法域名驗證)時:
一、添加容許源Access-Control-Allow-Origin
爲 $http_origin
(可根據業務須要更改)
二、添加容許認證Access-Control-Allow-Credentials
爲 true
,容許接收客戶端 Cookie(可根據業務須要更改。 但要注意,當設置爲true
時,Access-Control-Allow-Origin
不容許設置爲 *)
三、添加容許的方法,暴露的首部.net
至此,完成跨域請求正確響應。代理
以上,是對跨域請求在Web Server的解決方案,主要是經過響應 OPTIONS
方法和添加容許源來解決。
固然,若是本地開發中,能夠在利用 webpack-dev-server
的 proxy 選項來快速解決跨域問題:
示例以下:
// webpack.congf.js module.exports = { //... devServer: { proxy: { '/api': { target: 'http://localhost:3000', pathRewrite: {'^/api' : ''} } } } }
當訪問地址如 /api/foo?q=bar
時,則經過代理訪問的實際地址是: http://localhost:3000/foo?q=bar
CORS跨域請求並不魔幻,理解 CORS 的含義,根據規則去找方法就迎刃而解了。但願能幫助到你們。