nginx通過CORS實現跨域
https://www.cnblogs.com/sunmmi/articles/5956554.html
1.CORS是一個W3C標準,全稱是跨域資源共享(Cross-origin resource sharing)。它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
當前幾乎所有的瀏覽器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome 3+)都可通過名為跨域資源共享(Cross-Origin Resource Sharing)的協議支援AJAX跨域呼叫。
Chrome,Firefox,Opera,Safari都使用的是XMLHttpRequest2物件,IE使用XDomainRequest。
簡單來說就是跨域的目標伺服器要返回一系列的Headers,通過這些Headers來控制是否同意跨域。跨域資源共享(CORS)也是未來的跨域問題的標準解決方案。
CORS提供如下Headers,Request包和Response包中都有一部分。
2.HTTP Response Header
1 2 3 4 5 6 |
|
HTTP Request Header
1 2 |
|
其中最敏感的就是Access-Control-Allow-Origin這個Header, 它是W3C標準裡用來檢查該跨域請求是否可以被通過。(Access Control Check)。如果需要跨域,解決方法就是在資源的頭中加入Access-Control-Allow-Origin 指定你授權的域。
啟用CORS請求
假設您的應用已經在example.com上了,而您想要從www.example2.com提取資料。一般情況下,如果您嘗試進行這種型別的AJAX呼叫,請求將會失敗,而瀏覽器將會出現源不匹配的錯誤。利用CORS後只需www.example2.com 服務端新增一個HTTP Response頭,就可以允許來自example.com的請求。
將Access-Control-Allow-Origin新增到某網站下或整個域中的單個資源
1 2 |
|
將允許任何域向您提交請求
1 2 |
|
3.提交跨域請求
如果伺服器端已啟用了CORS,那麼提交跨域請求就和普通的XMLHttpRequest請求沒什麼區別。例如現在example.com可以向www.example2.com提交請求。
1 2 3 4 5 6 7 8 |
|
- 對於簡單請求,如GET,只需要在HTTP Response後新增Access-Control-Allow-Origin。
- 對於非簡單請求,比如POST、PUT、DELETE等,瀏覽器會分兩次應答。第一次preflight(method: OPTIONS),主要驗證來源是否合法,並返回允許的Header等。第二次才是真正的HTTP應答。所以伺服器必須處理OPTIONS應答。
流程如下
- 首先檢視http頭部有無origin欄位;
- 如果沒有,或者不允許,直接當成普通請求處理,結束;
- 如果有並且是允許的,那麼再看是否是preflight(method=OPTIONS);
- 如果是preflight,就返回Allow-Headers、Allow-Methods等,內容為空;
- 如果不是preflight,就返回Allow-Origin、Allow-Credentials等,並返回正常內容。
用偽程式碼表示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Nginx配置例項
例項一:允許example.com的應用在www.example2.com上跨域提取資料
在nginx.conf裡找到server項,並在裡面新增如下配置
1 2 3 4 5 6 7 8 |
|
如果需要允許來自任何域的訪問,可以這樣配置
1 |
|
註釋如下
第一條指令:授權從example.com的請求(必需)
第二條指令:當該標誌為真時,響應於該請求是否可以被暴露(可選)
第三條指令:允許指令碼訪問的返回頭(可選)
第四條指令:指定請求的方法,可以是GET, POST, OPTIONS, PUT, DELETE等(可選)
重啟Nginx
1 |
|
測試跨域請求
1 |
|
成功時,響應頭是如下所示
1 2 3 |
|
例項二:Nginx允許多個域名跨域訪問
由於Access-Control-Allow-Origin引數只允許配置單個域名或者 * ,當我們需要允許多個域名跨域訪問時可以用以下幾種方法來實現。
- 方法一
如需要允許使用者請求來自www.example.com、m.example.com、wap.example.com訪問www.example2.com域名時,返回頭Access-Control-Allow-Origin,具體配置如下
在nginx.conf裡面,找到server項,並在裡面新增如下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
- 方法二
如需要允許使用者請求來自localhost、www.example.com或m.example.com的請求訪問xxx.example2.com域名時,返回頭Access-Control-Allow-Origin,具體配置如下
在Nginx配置檔案中xxx.example2.com域名的location /下配置以下內容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
- 方法三
如需要允許使用者請求來自*.example.com訪問xxx.example2.com域名時,返回頭Access-Control-Allow-Origin,具體配置如下
在Nginx配置檔案中xxx.example2.com域名的location /下配置以下內容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
- 方法四
如需要允許使用者請求來自xxx1.example.com或xxx1.example1.com訪問xxx.example2.com域名時,返回頭Access-Control-Allow-Origin,具體配置如下
在Nginx配置檔案中xxx.example2.com域名的location /下配置以下內容
1 2 3 4 5 6 |
|
例項三:Nginx跨域配置並支援DELETE,PUT請求
預設Access-Control-Allow-Origin開啟跨域請求只支援GET、HEAD、POST、OPTIONS請求,使用DELETE發起跨域請求時,瀏覽器出於安全考慮會先發起OPTIONS請求,伺服器端接收到的請求方式就變成了OPTIONS,所以引起了伺服器的405 Method Not Allowed。
解決方法
首先要對OPTIONS請求進行處理
1 2 3 4 5 6 |
|
當請求方式為OPTIONS時設定Allow的響應頭,重新處理這次請求。這樣發出請求時第一次是OPTIONS請求,第二次才是DELETE請求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
例項四:更多配置示例
- 示例一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
- 示例二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
其它技巧
Apache中啟用CORS
在httpd配置或.htaccess檔案中新增如下語句
1 2 |
|
PHP中啟用CORS
通過在服務端設定Access-Control-Allow-Origin響應頭
- 允許所有來源訪問
1 2 3 |
|
- 允許來自特定源的訪問
1 2 3 |
|
- 配置多個訪問源
由於瀏覽器實現只支援了單個origin、*、null,如果要配置多個訪問源,可以在程式碼中處理如下
1 2 3 4 5 6 7 8 9 10 |
|
HTML中啟用CORS
1 |
|
參考文件
http://www.google.com
http://t.cn/RZEYPmD
http://t.cn/RhcAN2d
http://to-u.xyz/2016/06/30/nginx-cors/
http://coderq.github.io/2016/05/13/cross-domain/
來自:http://www.yunweipai.com/archives/9381.html