今天就跟大家聊聊有關Nginx跨域訪問問題有哪些,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
一、什么是跨域
簡單地理解就是因為JavaScript同源策略的限制,a.com 域名下的js無法操作b.com或是c.a.com域名下的對象。
同源是指相同的協議、域名、端口。特別注意兩點:
如果是協議和端口造成的跨域問題“前臺”是無能為力的,
在跨域問題上,域僅僅是通過“協議+域名+端口”來識別,兩個不同的域名即便指向同一個ip地址,也是跨域的。
二、常見跨域情況
URL 說明 是否允許通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允許 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下不同文件夾 允許 http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名,不同端口 不允許 http://www.a.com/a.js https://www.a.com/b.js 同一域名,不同協議 不允許 http://www.a.com/a.js 域名和域名對應ip 不允許 http://www.a.com/a.js http://script.a.com/b.js 主域相同,子域不同 不允許 http://www.a.com/a.js http://a.com/b.js 同一域名,不同二級域名(同上)不允許(cookie這種情況下也不允許訪問) http://www.cnblogs.com/a.js http://www.a.com/b.js 不同域名 不允許
特別注意兩點:
第一,如果是協議和端口造成的跨域問題“前臺”是無能為力的,第二:在跨域問題上,域僅僅是通過“URL的首部”來識別而不會去嘗試判斷相同的ip地址對應著兩個域或兩個域是否在同一個ip上?!癠RL的首部”指window.location.protocol +window.location.host,也可以理解為“Domains, protocols and ports must match”。
三、跨域解決方案
有多種,大多是利用JS Hack
1、document.domain+iframe的設置
2、動態創建script
3、利用iframe和location.hash
4、window.name實現的跨域數據傳輸
5、使用HTML5 postMessage
6、利用flash 以上方案見http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m5
7、nginx反向代理 這個方法一般很少有人提及,但是他可以不用目標服務器配合,不過需要你搭建一個中轉nginx服務器,用于轉發請求。
8、Jquery JSONP(本質上就是動態創建script)http://www.cnblogs.com/chopper/archive/2012/03/24/2403945.html
9、跨域資源共享(CORS) 這就是我們要介紹的跨域解決方案,也是未來的跨域問題的標準解決方案
四、關于CORS
CORS: 跨域資源共享(Cross-Origin Resource Sharing)http://www.w3.org/TR/cors/
當前幾乎所有的瀏覽器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome 3+)都可通過名為跨域資源共享(Cross-Origin Resource Sharing)的協議支持ajax跨域調用。(see: http://caniuse.com/#search=cors)
Chrome, Firefox, Opera and Safari 都使用的是 XMLHttpRequest2 對象, IE使用XDomainRequest。XMLHttpRequest2的Request屬性:open()、setRequestHeader()、timeout、withCredentials、upload、send()、send()、abort()。
XMLHttpRequest2的Response屬性:status、statusText、getResponseHeader()、getAllResponseHeaders()、entity、overrideMimeType()、responseType、response、responseText、responseXML。
1、啟用 CORS 請求
假設您的應用已經在 example.com 上了,而您想要從 www.example2.com 提取數據。一般情況下,如果您嘗試進行這種類型的 AJAX 調用,請求將會失敗,而瀏覽器將會出現“源不匹配”的錯誤。利用 CORS,www.example2.com 服務端只需添加一個HTTP Response頭,就可以允許來自 example.com 的請求:
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: true(可選)
可將 Access-Control-Allow-Origin 添加到某網站下或整個域中的單個資源。要允許任何域向您提交請求,請設置如下:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true(可選)
其實,該網站 (html5rocks.com) 已在其所有網頁上均啟用了 CORS。啟用開發人員工具后,您就會在我們的響應中看到 Access-Control-Allow-Origin 了。
2、CORS方法實現跨域請求
要實現CORS跨域,服務端需要這個一個流程:https://cache.yisu.com/upload/information/20200309/32/45401.jpg
對于簡單請求,如GET,只需要在HTTP Response后添加Access-Control-Allow-Origin。
對于非簡單請求,比如POST、PUT、DELETE等,瀏覽器會分兩次應答。第一次preflight(method: OPTIONS),主要驗證來源是否合法,并返回允許的Header等。第二次才是真正的HTTP應答。所以服務器必須處理OPTIONS應答。
http://enable-cors.org/server_nginx.html 這里是一個nginx啟用COSR的參考配置。
流程如下:
首先查看http頭部有無origin字段;
如果沒有,或者不允許,直接當成普通請求處理,結束;
如果有并且是允許的,那么再看是否是preflight(method=OPTIONS);
如果是preflight,就返回Allow-Headers、Allow-Methods等,內容為空;
如果不是preflight,就返回Allow-Origin、Allow-Credentials等,并返回正常內容。
首先,在遠端需要訪問的主機上做設置,假如遠端主機是nginx服務,那么添加如下信息即可。
server { listen 80; server_name tangxiaoyue.com; if ( $http_user_agent = "Mozilla/5.0"){ return 403; } location / { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # Custom headers and headers various browsers *should* be OK with but aren't add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 后面省略。。。 } }
五、nginx反向代理解決跨域
禁止跨域問題其實是瀏覽器的一種安全行為,而現在的大多數解決方案都是用標簽可以跨域訪問的這個漏洞或者是技巧去完成,但都少不了目標服務器做相應的改變,如果目標服務器無法改變的時候,就需要本地服務器實現,本地實現的話,需要搭建一個nginx并把相應代碼部署在它的下面,由頁面請求本域名的一個地址,轉由nginx代理到目標服務器處理后返回結果給頁面,而且這一切都是同步的。
假如代理服務器地址是 www.c.com/proxy/html/api/msg?method=1=2; www.c.com是nginx主機地址
遠端服務器地址:http://www.b.com/api/msg?method=1=2
在nginx服務器上做如下配置
在location下面再添加一個location。
location ^~/proxy/html/{
rewrite ^/proxy/html/(.*)$ /$1 break;
proxy_pass http://www.b.com/;
}
以下做一個解釋:
1.'^~ /proxy/html/ ‘
就像上面說的一樣是一個匹配規則,用于攔截請求,匹配任何以 /proxy/html/開頭的地址,匹配符合以后,停止往下搜索正則。
2.rewrite ^/proxy/html/(.*)$ /$1 break;
代表重寫攔截進來的請求,并且只能對域名后邊的除去傳遞的參數外的字符串起作用,例如www.c.com/proxy/html/api/msg?method=1=2重寫。只對/proxy/html/api/msg重寫。
rewrite后面的參數是一個簡單的正則 ^/proxy/html/(.*)$ ,$1代表正則中的第一個(),$2代表第二個()的值,以此類推。
break代表匹配一個之后停止匹配。
看完上述內容,你們對Nginx跨域訪問問題有哪些有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。