前言:跨域配置可以分為:前端配置,后端配置,nginx配置, 這里分別介紹
為什么會(huì)發(fā)生ajax跨域呢?
- 瀏覽器限制
瀏覽器出于安全的考慮,當(dāng)它發(fā)現(xiàn)請求是跨域的時(shí)候,它會(huì)做一些校驗(yàn),如果校驗(yàn)不通過,就會(huì)報(bào)跨域安全問題。 - 請求跨域
所謂同源是指:域名、協(xié)議、端口相同
如果發(fā)出去的請求不是本域的,協(xié)議、域名、端口,任何一個(gè)不一樣,瀏覽器就認(rèn)為是跨域的
前端配置:
jsonp:
利用script標(biāo)簽請求數(shù)據(jù)(不推薦)
存在問題:只能發(fā)送get請求,接收數(shù)據(jù)和配置較為麻煩
利用node中間件proxy配置跨域(此處只介紹vite中的代理配置)
node proxy跨域原理圖

1636428866625.png
vite.config.js中
proxy: {
1.如發(fā)送請求/api/xxx,此時(shí)請求攔/api
'/api': {
2.路徑轉(zhuǎn)發(fā),此時(shí)請求地址變?yōu)閔ttp://localhost:5001/api/xxxx
target: 'http://localhost:5001',
changeOrigin: true,//請求改變源,此時(shí)nginx可以獲取到真實(shí)的請求ip
3.路徑重寫,此時(shí)請求變成了http://localhost:5001/xxxx,
path.replace(/^/api/, ‘’)-->將請求地址中的api去除了
rewrite: (path) => path.replace(/^/api/, ‘’)
}
}
說明:
請求攔截的前綴如請求地址中 http://localhost:5001/api
注意:請求域名必須為http://localhost:5001/才會(huì)進(jìn)行攔截(你本地訪問頁面的起始地址), 如http://8.135.1.141/api則不會(huì)進(jìn)行攔截,所以需要配置跨域的話建議把url寫成:/api就行
如在 .env.serve-dev文件中設(shè)置VITE_APP_BASE_URL = '/api'
后端配置跨域(此處針對java后臺(tái))
網(wǎng)關(guān)處配置跨域(spring-gateway)
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
# 允許攜帶認(rèn)證信息
# 允許跨域的源(網(wǎng)站域名/ip),設(shè)置*為全部
# 允許跨域請求里的head字段,設(shè)置*為全部
# 允許跨域的method, 默認(rèn)為GET和OPTIONS,設(shè)置*為全部
# 跨域允許的有效期
allow-credentials: true
allowed-origins: "*"
allowed-headers: "*"
allowed-methods:
- OPTIONS
- GET
- POST
- PUT
- DELETE
#max-age: 3600
如果只是一個(gè)java服務(wù),沒有網(wǎng)關(guān)
給controller添加@CrossOrigin,如:
@CrossOrigin
public class TestController {
}
注意,網(wǎng)關(guān)跨域配置和服務(wù)跨域配置只能寫一個(gè)不然會(huì)報(bào)多個(gè)跨域配置的問題
利用nginx配置跨域和頁面壓縮(推薦)
這里貼上vue3-admin-template里的nginx配置
[root@iZwz9izs4qf3b81quqwp61Z http]# nginx-gzip-cors.conf
server {
listen 80 ;
#頁面壓縮配置(1M->300K)
location /vue3-admin-template{
#gzip模塊設(shè)置
#開啟gzip壓縮輸出
gzip on;
#最小壓縮文件大小
gzip_min_length 1k;
#壓縮緩沖區(qū)
gzip_buffers 4 16k;
#壓縮版本(默認(rèn)1.1,前端如果是squid2.5請使用1.0)
gzip_http_version 1.0;
#壓縮等級(1M能壓縮到300K左右,提高首頁加載速度)
gzip_comp_level 4;
#壓縮類型,默認(rèn)就已經(jīng)包含text/html,所以下面就不用再寫了,寫上去也不會(huì)有問題,但是會(huì)有一個(gè)warn。
gzip_types text/plain application/x-javascript application/javascript text/javascript text/xml text/css;
#選擇支持vary header,可以讓前端的緩存服務(wù)器緩存經(jīng)過gzip壓縮的頁面;
gzip_vary on;
root /opt/nginx/html;
index index.html;;
}
#網(wǎng)關(guān)(請求跨域配置)
location ^~/micro-service-api/ {
proxy_pass http://8.135.1.141:10156/;
#允許的請求頭
add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS,POST,PUT,DELETE' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
add_header Access-Control-Max-Age 3600;
# 頭轉(zhuǎn)發(fā)
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_connect_timeout 1000;
proxy_read_timeout 1000;
# 跨域配置
if ($request_method = OPTIONS ) { return 200; }
}
location /file/{
root /opt/nginx/html;
}
}
總結(jié):
前端proxy跨域配置:當(dāng)后端和linux服務(wù)器中不做配置時(shí),進(jìn)行配置使用-->dev
優(yōu)點(diǎn):前端可以單獨(dú)進(jìn)行跨域配置,不用依賴于后端
缺點(diǎn):前端調(diào)試的時(shí)候頁面的路徑是localhost,無法直接獲取到請求的真實(shí)地址無法更好的調(diào)試
后端跨域配置:當(dāng)沒有服務(wù)沒有上nginx服務(wù)器上時(shí)使用-->dev,prod環(huán)境都可以使用;
nginx跨域配置(推薦):對原有的開發(fā)代碼無侵入性,且效率較高,特別是nginx的壓縮配置極大的提高了頁面首次的加載速度-->dev,prod;
這邊建議:配置跨域順序:nginx->后端(網(wǎng)關(guān)->服務(wù))->web
nginx,后端,web 配置跨域只能配置一端,不然瀏覽器會(huì)報(bào)多個(gè)跨域頭的問題