CORS 跨域問題, 以及做爲api server 的正確配置, 後臺 nginx 配置

服務器的同源策略: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) 請求方法是如下三種方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的頭信息不超出如下幾種字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限於三個值application/x-www-form-urlencodedmultipart/form-datatext/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

相關文章
相關標籤/搜索