Nginx如何處理跨域請求。
(本文適用於初學者)api
關於Nginx的用途,聽到最多的兩個詞,就是:跨域
負載均衡不屬於現階段要學習的內容,重點來看一看端口轉發,本文用它來解決跨域請求的問題。瀏覽器
咱們須要知道,同源的三要素:協議、域名、端口。
若是比較兩個地址,只要三者中只要有任何一個不一樣,就算跨域。安全
// 協議:http // 域名:localhost // 端口:8011 http://localhost:8011
出於安全緣由,瀏覽器限制從腳本(好比JavaScript)內發起的跨源HTTP請求。
若是瀏覽器檢測到跨域,它會嘗試發起一次請求,而後查看返回的內容中,是否一個有容許跨域請求的標記(CORS響應頭),若是有正確的標記,那麼就不攔截;若是沒有標記,瀏覽器就會阻止這個請求。並報錯。服務器
在先後臺分離的項目中,前臺和後臺分別運行在不一樣的端口上。負載均衡
因此前臺向後臺發起請求時,會由於跨域,而被瀏覽器攔截下來。學習
瀏覽器錯誤信息:url
這時解決方案有兩個:spa
第一種方法,顯然不安全,開放跨域意味着,瀏覽器再也不進行攔截。若是前臺代碼被篡改,把後臺的地址指向黑客的服務器,那麼會對用戶形成損失。code
第二種方法,想辦法變成同一個域,這就輪到Nginx出場了!
首先要明白,是誰把前臺向後臺的請求攔截下來的?不是後臺,而是瀏覽器。
若是要避免跨域,只要讓瀏覽器認爲「我正在向同一個域發起請求」,就能夠了。
假設前臺使用4200端口,後臺使用8080端口,那麼,再加入一個8011端口,做爲用戶訪問時鏈接的端口。
在前臺的代碼中,會有攔截器,若是發現某個請求是指向後臺的,就會在Url中加入一個特殊的標識(好比加一個/api/做爲前綴)
// header中帶有do_not_intercept,且值爲true,則不添加url前綴 if (('true' !== req.headers.get(YunzhiInterceptor.DONT_INTERCEPT_HEADER_KEY)) && !url.startsWith('https://') && !url.startsWith('http://')) { url = '/api/' + url; }
如今,不管是指向前臺仍是後臺的請求,都會發送到8011端口,只不過,指向後臺的請求會有一個/api/前綴。
接下來使用Nginx監聽8011端口,當接收到請求時,根據是否有前綴,來判斷此請求交給前臺或後臺處理。
過程如圖:
上圖就是轉發的原理。
使用Nginx端口轉發,本質上就是:讓瀏覽器認爲前臺和後臺是同一個域,就不會產生跨域請求。開發者事先約定好,根據不一樣的請求地址,來訪問不一樣的服務器。Nginx接收到數據以後,根據地址,轉發給相應的服務器來處理。若是須要另外安排其餘的服務,來實現文件上傳功能的話,只須要把URL處理一下,加上不一樣的前綴便可。