nginx配置解決跨域訪問(wèn)的方法詳解
后端環(huán)境
正常訪問(wèn)端口8058
經(jīng)過(guò)nginx配置(文末具體展示)后,去除端口,如下:
前端開(kāi)發(fā)環(huán)境
1. 配置開(kāi)發(fā)和生產(chǎn)的環(huán)境變量
.env.development
文件
# API服務(wù)路徑 VITE_APP_BASE_URL = ""
.env.production
文件
# API服務(wù)路徑,注意沒(méi)有端口號(hào),是經(jīng)過(guò)nginx處理后的后端服務(wù)地址 VITE_APP_BASE_URL = "http://192.168.1.4/"
2. vite.config.ts 文件配置開(kāi)發(fā)代理
import { warpperEnv } from "./build"; import { UserConfigExport, ConfigEnv, loadEnv } from "vite"; /** 當(dāng)前執(zhí)行node命令時(shí)文件夾的地址(工作目錄) */ const root: string = process.cwd(); export default ({ command, mode }: ConfigEnv): UserConfigExport => { const { VITE_CDN, VITE_PORT, VITE_COMPRESSION, VITE_PUBLIC_PATH } = warpperEnv(loadEnv(mode, root)); return { base: VITE_PUBLIC_PATH, root, resolve: { alias }, // 服務(wù)端渲染 server: { // 是否開(kāi)啟 https https: false, // 端口號(hào) port: VITE_PORT, host: "0.0.0.0", // 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy proxy: { "^/api": { target: "http://192.168.1.4:8058", changeOrigin: true, rewrite: path => path.replace(/^\/api/, "") } } }, // 后面省略... } };
3. http 文件封裝 axios,使用環(huán)境變量配置的基礎(chǔ)API路徑
// 相關(guān)配置請(qǐng)參考:www.axios-js.com/zh-cn/docs/#axios-request-config-1 const defaultConfig: AxiosRequestConfig = { // 請(qǐng)求地址 baseURL: import.meta.env.VITE_APP_BASE_URL, // 請(qǐng)求超時(shí)時(shí)間 timeout: 5000, headers: { Accept: "application/json, text/plain, */*", "Content-Type": "application/json", "X-Requested-With": "XMLHttpRequest" } };
4. api 文件里使用示例
import { http } from "@/utils/http"; export type UserResult = { success: boolean; data: { username: string; roles: Array<string>; accessToken: string; refreshToken: string; expires: Date; }; }; /** 登錄 */ export const getLogin = (data?: object) => { return http.request<UserResult>("post", "/api/login", { data }); };
5. 開(kāi)發(fā)環(huán)境項(xiàng)目預(yù)覽
由于使用了代理,所以不會(huì)有跨域的問(wèn)題,如圖:
前端生產(chǎn)環(huán)境
生產(chǎn)環(huán)境采用Tomcat,前端項(xiàng)目打包好后,放在Tomcat的 webapps/ROOT
目錄下即可,如圖:
啟動(dòng)Tomcat,雙擊 apache-tomcat-8.5.93/bin/
目錄下的 startup.bat
,linux機(jī)器到 bin
目錄下,運(yùn)行 ./startup.sh
訪問(wèn),Tomcat默認(rèn)端口為8080,訪問(wèn)后臺(tái)接口報(bào)跨域錯(cuò)誤
nginx配置后,去除端口,訪問(wèn)正常
nginx配置
以上可以看出,nginx配置的目的,就是去除前后端的端口差異,從而解決跨域的問(wèn)題。配置文件 nginx/conf/nginx.conf
修改如下:
server { listen 80; # IP/域名都可以 server_name http://192.168.1.4; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; proxy_pass http://192.168.1.4:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 5; } location ^~ /api/ { add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } proxy_pass http://192.168.1.4:8058/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 5; } }
疑問(wèn)解答
1. 此示例項(xiàng)目,本地模擬的線上環(huán)境,操作系統(tǒng) windows,后端服務(wù) nodejs。換成 linux 系統(tǒng)或其他后端服務(wù)(如:SpringBoot 等)還適用嗎,為什么?
答:同樣適用。
因?yàn)榭缬騿?wèn)題是瀏覽器為了安全保證,當(dāng)你前端服務(wù)訪問(wèn)跨域資源時(shí),被瀏覽器默認(rèn)禁止了,所以和后端服務(wù)是什么,沒(méi)有必然關(guān)系;所以解決問(wèn)題的思路也是讓我們的訪問(wèn)請(qǐng)求,達(dá)到瀏覽器的要求,即不跨域(同一域名/IP、端口、協(xié)議),那當(dāng)然使用 nginx
就可以。
2. 前端請(qǐng)求里的代理里的 ^api,和nginx配置里的 ^~ /api/ 有什么關(guān)系?
答:有關(guān)系,但是不是你想象的關(guān)系。
首先我們要確認(rèn),你的實(shí)際的請(qǐng)求地址里,其實(shí)不包含 api
這段路徑。如圖:
開(kāi)發(fā)環(huán)境加這個(gè)只是為了代理區(qū)分,因?yàn)槟憧赡芤?qǐng)求多個(gè)不同域名的后端服務(wù):我可以在 vite.config.ts
文件的 proxy
里再加一個(gè)以 ^/auth
開(kāi)頭的,導(dǎo)向其他域名的后端服務(wù)。
其次代碼里也可以看到 rewrite: path => path.replace(/^\/api/, "")
,所以實(shí)際的請(qǐng)求地址,最終是去掉了 api
。
那為什么nginx里要配置成 api
呢?
因?yàn)榫€上環(huán)境是沒(méi)有運(yùn)行代理的,也就是說(shuō) rewrite: path => path.replace(/^\/api/, "")
這一段是沒(méi)有生效的,那你前端實(shí)際的請(qǐng)求地址就是 http://192.168.1.4/api/login
,而真正的地址里沒(méi)有 api
這一段,所以多出來(lái)的這一段,正好讓nginx去代理,^~ /api/
變成 http://192.168.1.4:8058/
,從而使請(qǐng)求地址變成 http://192.168.1.4:8058/login
。
3. 接上,這兩 api 雖然不是我想象的關(guān)系,但是事實(shí)上必須保持一致,有沒(méi)有什么可以解耦的辦法?
答:有。
nginx一般不會(huì)去隨便改動(dòng),所以我們的解決辦法優(yōu)先放在前端,讓前端去適配nginx。
參考 vite.config.ts
文件的代理地址替換,那我們?cè)趯?shí)際請(qǐng)求地址時(shí),也可以做一個(gè)替換處理:在 http
文件里的請(qǐng)求攔截器中,判斷是否生產(chǎn)環(huán)境,如果是,則替換 ^api
為nginx配置的開(kāi)頭路徑即可。
4. 接上,vite.config.ts 可以配置多個(gè)代理,nginx也可以配置多個(gè)后端服務(wù),但是 http 文件里的 axios 封裝只有一個(gè) baseURL?
答:不是有攔截器嗎。
env
環(huán)境配置里增加多個(gè)域名字段,假如以 auth
開(kāi)頭是另一個(gè)域名,那就在攔截器里使用條件判斷,如果是 auth
開(kāi)頭,修改 config.baseURL
地址。
或者封裝多個(gè) axois
?不建議,代碼重復(fù)率又高了。
5. 既然nginx已經(jīng)把 api 開(kāi)頭的都代理到了后端服務(wù),那我前端就不能有 api 開(kāi)頭的路由?
答:可以。
看看訪問(wèn)路徑,前端是哈希路由,有 #
號(hào)分隔的。如果是 history
路由呢,有試過(guò)的同學(xué)可以在評(píng)論區(qū)吱個(gè)聲。
到此這篇關(guān)于nginx配置解決跨域訪問(wèn)的方法詳解的文章就介紹到這了,更多相關(guān)nginx解決跨域訪問(wèn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Nginx跨域使用字體文件的配置方法
- nginx服務(wù)器配置解決ajax的跨域問(wèn)題
- nginx服務(wù)器通過(guò)配置來(lái)解決API的跨域問(wèn)題
- Nginx配置跨域請(qǐng)求Access-Control-Allow-Origin * 詳解
- nginx 配置跨域失效修復(fù)的方法示例
- 通過(guò)Nginx代理轉(zhuǎn)發(fā)配置實(shí)現(xiàn)跨域的方法(API代理轉(zhuǎn)發(fā))
- ubuntu nginx安裝及服務(wù)配置跨域問(wèn)題處理方式
- Nginx?跨域配置的具體實(shí)現(xiàn)
- Nginx 配置跨域的實(shí)現(xiàn)及常見(jiàn)問(wèn)題解決
相關(guān)文章
nginx worker進(jìn)程循環(huán)的實(shí)現(xiàn)
這篇文章主要介紹了nginx worker進(jìn)程循環(huán)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Nginx+uwsgi+ssl配置https的詳細(xì)步驟
nginx是一個(gè)輕量級(jí)的web服務(wù)器,在處理靜態(tài)資源和高并發(fā)有優(yōu)勢(shì),uwsgi是一個(gè)基于python的高效率的協(xié)議,處理后端和動(dòng)態(tài)網(wǎng)頁(yè)有優(yōu)勢(shì),我這里使用的是Ubuntu18.04版本,服務(wù)器在阿里云,感興趣的朋友跟隨小編一起看看吧2023-10-10Nginx配置負(fù)載均衡時(shí)訪問(wèn)地址無(wú)法生效的解決方法
本文主要介紹了Nginx配置負(fù)載均衡時(shí)訪問(wèn)地址無(wú)法生效的解決方法,例如負(fù)載均衡策略的設(shè)置是否正確、是否存在拼寫(xiě)錯(cuò)誤等,下面就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下2023-09-09Nginx接收Http協(xié)議請(qǐng)求轉(zhuǎn)發(fā)使用Https協(xié)議的問(wèn)題
這篇文章主要介紹了Nginx接收Http協(xié)議請(qǐng)求轉(zhuǎn)發(fā)使用Https協(xié)議,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06Windows Server 2016 MySQL數(shù)據(jù)庫(kù)安裝配置詳細(xì)安裝教程
這篇文章主要介紹了Windows Server 2016 MySQL數(shù)據(jù)庫(kù)安裝配置詳細(xì)安裝教程,需要的朋友可以參考下2017-08-08