(本文適用于初學(xué)者)
一、Nginx
關(guān)于Nginx的用途,聽到最多的兩個(gè)詞,就是:
端口轉(zhuǎn)發(fā)
負(fù)載均衡
負(fù)載均衡不屬于現(xiàn)階段要學(xué)習(xí)的內(nèi)容,重點(diǎn)來看一看端口轉(zhuǎn)發(fā),本文用它來解決跨域請求的問題。
二、CROS 跨域資源共享
我們需要知道,同源的三要素:協(xié)議、域名、端口。
如果比較兩個(gè)地址,只要三者中只要有任何一個(gè)不同,就算跨域。
// 協(xié)議:http// 域名:localhost// 端口:8011http://localhost:8011
出于安全原因,瀏覽器限制從腳本(比如JavaScript)內(nèi)發(fā)起的跨源HTTP請求。
如果瀏覽器檢測到跨域,它會嘗試發(fā)起一次請求,然后查看返回的內(nèi)容中,是否一個(gè)有允許跨域請求的標(biāo)記(CORS響應(yīng)頭),如果有正確的標(biāo)記,那么就不攔截;如果沒有標(biāo)記,瀏覽器就會阻止這個(gè)請求。并報(bào)錯。
三、項(xiàng)目中為何產(chǎn)生跨域
在前后臺分離的項(xiàng)目中,前臺和后臺分別運(yùn)行在不同的端口上。
所以前臺向后臺發(fā)起請求時(shí),會因?yàn)榭缬?,而被瀏覽器攔截下來。
瀏覽器錯誤信息:
這時(shí)解決方案有兩個(gè):
開放跨域請求
使跨域變成同源
第一種方法,顯然不安全,開放跨域意味著,瀏覽器不再進(jìn)行攔截。如果前臺代碼被篡改,把后臺的地址指向黑客的服務(wù)器,那么會對用戶造成損失。
第二種方法,想辦法變成同一個(gè)域,這就輪到Nginx出場了!
四、使用Nginx轉(zhuǎn)發(fā)
首先要明白,是誰把前臺向后臺的請求攔截下來的?不是后臺,而是瀏覽器。
如果要避免跨域,只要讓瀏覽器認(rèn)為“我正在向同一個(gè)域發(fā)起請求”,就可以了。
假設(shè)前臺使用4200端口,后臺使用8080端口,那么,再加入一個(gè)8011端口,作為用戶訪問時(shí)連接的端口。
在前臺的代碼中,會有攔截器,如果發(fā)現(xiàn)某個(gè)請求是指向后臺的,就會在Url中加入一個(gè)特殊的標(biāo)識(比如加一個(gè)/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;}
現(xiàn)在,無論是指向前臺還是后臺的請求,都會發(fā)送到8011端口,只不過,指向后臺的請求會有一個(gè)/api/前綴。
接下來使用Nginx監(jiān)聽8011端口,當(dāng)接收到請求時(shí),根據(jù)是否有前綴,來判斷此請求交給前臺或后臺處理。
過程如圖:
上圖就是轉(zhuǎn)發(fā)的原理。
五、總結(jié)
使用Nginx端口轉(zhuǎn)發(fā),本質(zhì)上就是:讓瀏覽器認(rèn)為前臺和后臺是同一個(gè)域,就不會產(chǎn)生跨域請求。
開發(fā)者事先約定好,根據(jù)不同的請求地址,來訪問不同的服務(wù)器。
Nginx接收到數(shù)據(jù)之后,根據(jù)地址,轉(zhuǎn)發(fā)給相應(yīng)的服務(wù)器來處理。
如果需要另外安排其他的服務(wù),來實(shí)現(xiàn)文件上傳功能的話,只需要把URL處理一下,加上不同的前綴即可。