人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

利用Nginx代理如何解決前端跨域問題詳析

發(fā)布日期:2022-01-29 12:01 | 文章來源:gibhub

Nginx(發(fā)音同“engine X”)是異步框架的網(wǎng)頁服務器,也可以用作反向代理、負載平衡器和HTTP緩存。

本文將講述如何使用 Nginx 在 Web 前后端分離開發(fā)中實現(xiàn)路由的轉(zhuǎn)發(fā)。

Web 開發(fā)通常使用的是前后端分離的開發(fā)模式,即前端和后端分別進行開發(fā),前端通過 Ajax 請求后端的接口,將獲取數(shù)據(jù)將數(shù)據(jù)渲染到頁面上。前端開發(fā)會使用腳手架搭建前端開發(fā)環(huán)境,其底層通常會啟動一個本地服務器,通常使用的是 nodejs 的 Express 框架。而后端則是提供接口,一般是放在線上的一個開發(fā)用的域名下。

這在開發(fā)過程中會導致 跨域 問題,即在一個域名下的網(wǎng)頁,是無法通過 Ajax 請求另一個(不同源)域名下的接口 API 的。這是瀏覽器的同源策略,是瀏覽器的一個非常重要的安全策略。

解決這個問題的其中一個方案是使用 代理。具體來說,就是在本地啟動一個服務器(如 localhost:4000),發(fā)送給該服務器的請求會根據(jù)請求路由(比如判斷 url 是否有前綴 /api)進行轉(zhuǎn)發(fā),分別轉(zhuǎn)發(fā)到前端開發(fā)的服務器(如 localhost:3000),以及后端服務器(比如 dev.yoursite.com)。這樣通過一個代理服務器,因為請求的 api 都是同一個域名下的,自然就不會造成跨域問題,從而導致請求失敗。

下面我們就來講解如何使用 Nginx 來實現(xiàn)反向代理。

簡單認識 Nginx 配置文件

安裝好 Nginx 后,我們需要確定下 Nginx 的默認配置文件的位置。執(zhí)行命令 nginx -t,該命令會檢測 nginx 的默認配置文件語法是否正確,并進行測試,最后輸出結(jié)果。我們可以從輸出中得到默認配置文件所在的位置。

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

還有另外一種方法可以得到默認配置文件的位置,那就是執(zhí)行 nginx -h。該命令會輸出 nginx 的簡易幫助文檔,其中的 -c filename 的配置項說明也指出了默認配置項的路徑。

-c filename : set configuration file (default: /etc/nginx/nginx.conf)

通過這個文檔,我們也可以知道,使用 -c 配置項可以自定義配置文件。如果不指定文件,使用默認配置文件。

下面我們來修改一下 Nginx 到這個默認配置文件 nginx.config 來首先代理功能。

nginx.config 文件的 http 后面的代碼塊中,應該會有類似下面這行的代碼:

include /etc/nginx/conf.d/*.conf;

這行代碼的作用是將 /etc/nginx/conf.d 目錄下的后綴為 .conf 的文件內(nèi)容嵌入到引入位置中,作為配置的一部分執(zhí)行。

如果你是在 macOS 安裝的 Nginx,可能會有點不同。我使用 brew 安裝的 Nginx 為為 include servers/*;,對應嵌入的是 servers 目錄下的所有文件。

為什么會用到這種嵌入的語法呢?因為這樣我們就可以將不同項目需要用到的配置放到不同的配置文件里,好處就是可以快速地找到對應項目要修改的配置文件,不用擔心不小心修改了其他項目的配置。另外如果直接在 nginx.conf 上修改,使其變得臃腫。這符合設計模式的 單一職責原則。

此外,你可以會奇怪conf.d 目錄的命名為什么要加上 .d ?如果你使用 Linux 過一段時間,你會發(fā)現(xiàn)某些目錄或文件的末尾會加上一個 d,比如 httpd、crond、vsftpd 等。其實這是為了說明這些文件都屬于是 daemon(服務)。這里的服務指的是系統(tǒng)的服務,主要分為系統(tǒng)本身需要的服務,以及負責網(wǎng)絡的服務。我們的 conf.d 就是屬于后者。

編寫 Nginx 配置文件

我們在 conf.d 目錄下創(chuàng)建名為 demo.conf 的文件,寫入以下內(nèi)容,然后啟動 Nginx。

server {
 listen 5000;
 server_name localhost;
 location / {
 proxy_pass http://localhost:3000;
 }
 location /api/ {
 proxy_pass http://localhost:4000;
 }
}

該配置啟用了 localhost:5000 的服務器,將 localhost:5000 下開頭為 /api/ url 請求代理到了 localhost:4000(后端接口服務器)。其他請求則是代理到 localhost:3000(前端)。下面我們具體解析一下配置文件里面內(nèi)容的作用。

listen 設置了服務器的端口號,server_name 則設置了主機名。

location

location 表示進行路由的匹配,如果匹配則執(zhí)行對應代碼塊里的操作。location 可以使用 前綴匹配 以及 正則匹配(需要以 ~* 或 ~ 開頭)。我們這里的配置使用的是前綴匹配。

這里有個點需要注意一下,Nginx 的路由匹配和一般的按順序匹配第一個的路由匹配方案(比如后端的 gin、前端的 vue-router 的路由匹配方案)不同,nginx 匹配路由的方式為:

  1. 首先進行前綴匹配,遍歷所有的前綴匹配,從中選擇前綴匹配最長的;
  2. 然后會進行正則匹配,在所有正則匹配中,從前往后選擇第一個符合的;
  3. 如果能找到匹配的正則匹配,使用其對應的配置;如果沒有,則使用之前找到的那個最長的前綴匹配對應的配置。

所以,當請求為 localhost:5000/api/xx 時, / 和 /api/ 都能夠前綴匹配。根據(jù)規(guī)則,雖然位置更靠前的 / 也符合前綴匹配,但 /api 更長,所以最終匹配的是 /api。

proxy_pass

確定好匹配的 location 后,我們再看看 proxy_pass 又做了什么操作。proxy_pass 用于將請求路由映射到指定的協(xié)議和地址。本質(zhì)是將發(fā)送給 Nginx 的請求處理并發(fā)送到另一個服務器,然后將返回的數(shù)據(jù)作為 Nginx的返回數(shù)據(jù)返回。

proxy_pass 后如果使用的是 URI(端口后面至少有一個 /),那么 Nginx 就會 替換 掉 location 匹配的那部分字符。

listen 5000;
server_name localhost;
location /name/ {
 proxy_pass http://127.0.0.1/remote/; 
}
# localhost:5000/name/fstar
# 會被映射請求為
# 127.0.0.1/remote/fstar

可以看到,/name/ 的部分在映射時被移除(或者說是替換)了。

proxy_pass 后如果使用的是不是 URI(端口后沒有任何東西),Nginx 會將源請求完全映射到代理服務上:

listen 5000;
server_name localhost;
location /some/path/ {
 proxy_pass http://127.0.0.1;
}
# localhost:5000/some/path/x/y
# 會被映射請求為
# 127.0.0.1/some/path/x/y

這里的 /some/path 并沒有被移除。

我們的 demo.conf 文件的 proxy_pass 使用的不是 URI,所以是將路由完全映射到另一個服務。

思考題

請問,下面有兩段配置(區(qū)別是 proxy_pass 結(jié)尾是否有 /)?如果請求 /kite/api/xx,分別會映射為什么?

location /kite/api/ {
 proxy_pass http://localhost:5000;
}
location /kite/api/ {
 proxy_pass http://localhost:5000/;
}

前面我們講 proxy_pass 的時候說過,proxy_pass 后面如果不是 URI,會正常轉(zhuǎn)發(fā);如果是 URI,就移除 location 匹配的前綴再進行轉(zhuǎn)發(fā),體現(xiàn)的是替換路由的效果。上面這兩個配置的區(qū)別就在于末尾的這個 /,有 / 是 URI,沒有的不是 URI,從而導致完全不一樣的結(jié)果,依次分別為:

http://localhost:5000/kite/api/xx
http://localhost:5000/xx

所以,在寫 Nginx 配置的時候,一定要注意端口后面的 / 是否有必要保留。因為它的有無會導致兩種截然不同的效果。

參考文章

  • Nginx 官方文檔
  • stackoverflow - How do I rewrite URLs in a proxy response in NGINX

總結(jié)

到此這篇關(guān)于利用Nginx代理如何解決前端跨域問題的文章就介紹到這了,更多相關(guān)Nginx代理解決前端跨域內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

香港穩(wěn)定服務器

版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務

7x24全年不間斷在線

專屬顧問服務

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務熱線

關(guān)注
微信

關(guān)注官方微信
頂部