前言:跨域配置可以分為:前端配置贷岸,后端配置,nginx配置磷雇, 這里分別介紹
為什么會(huì)發(fā)生ajax跨域呢偿警?
- 瀏覽器限制
瀏覽器出于安全的考慮,當(dāng)它發(fā)現(xiàn)請(qǐng)求是跨域的時(shí)候唯笙,它會(huì)做一些校驗(yàn)螟蒸,如果校驗(yàn)不通過(guò),就會(huì)報(bào)跨域安全問(wèn)題崩掘。 - 請(qǐng)求跨域
所謂同源是指:域名七嫌、協(xié)議、端口相同
如果發(fā)出去的請(qǐng)求不是本域的苞慢,協(xié)議诵原、域名、端口枉疼,任何一個(gè)不一樣皮假,瀏覽器就認(rèn)為是跨域的
前端配置:
jsonp:
利用script標(biāo)簽請(qǐng)求數(shù)據(jù)(不推薦)
存在問(wèn)題:只能發(fā)送get請(qǐng)求,接收數(shù)據(jù)和配置較為麻煩
利用node中間件proxy配置跨域(此處只介紹vite中的代理配置)
node proxy跨域原理圖
1636428866625.png
vite.config.js中
proxy: {
1.如發(fā)送請(qǐng)求/api/xxx,此時(shí)請(qǐng)求攔/api
'/api': {
2.路徑轉(zhuǎn)發(fā),此時(shí)請(qǐng)求地址變?yōu)閔ttp://localhost:5001/api/xxxx
target: 'http://localhost:5001',
changeOrigin: true,//請(qǐng)求改變?cè)绰钗藭r(shí)nginx可以獲取到真實(shí)的請(qǐng)求ip
3.路徑重寫,此時(shí)請(qǐng)求變成了http://localhost:5001/xxxx,
path.replace(/^/api/, ‘’)-->將請(qǐng)求地址中的api去除了
rewrite: (path) => path.replace(/^/api/, ‘’)
}
}
說(shuō)明:
請(qǐng)求攔截的前綴如請(qǐng)求地址中 http://localhost:5001/api
注意:請(qǐng)求域名必須為http://localhost:5001/才會(huì)進(jìn)行攔截(你本地訪問(wèn)頁(yè)面的起始地址)惹资, 如http://8.135.1.141/api則不會(huì)進(jìn)行攔截,所以需要配置跨域的話建議把url寫成:/api就行
如在 .env.serve-dev文件中設(shè)置VITE_APP_BASE_URL = '/api'
后端配置跨域(此處針對(duì)java后臺(tái))
網(wǎng)關(guān)處配置跨域(spring-gateway)
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
# 允許攜帶認(rèn)證信息
# 允許跨域的源(網(wǎng)站域名/ip)航闺,設(shè)置*為全部
# 允許跨域請(qǐng)求里的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ù),沒(méi)有網(wǎng)關(guān)
給controller添加@CrossOrigin,如:
@CrossOrigin
public class TestController {
}
注意侮措,網(wǎng)關(guān)跨域配置和服務(wù)跨域配置只能寫一個(gè)不然會(huì)報(bào)多個(gè)跨域配置的問(wèn)題
利用nginx配置跨域和頁(yè)面壓縮(推薦)
這里貼上vue3-admin-template里的nginx配置
[root@iZwz9izs4qf3b81quqwp61Z http]# nginx-gzip-cors.conf
server {
listen 80 ;
#頁(yè)面壓縮配置(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請(qǐng)使用1.0)
gzip_http_version 1.0;
#壓縮等級(jí)(1M能壓縮到300K左右,提高首頁(yè)加載速度)
gzip_comp_level 4;
#壓縮類型乖杠,默認(rèn)就已經(jīng)包含text/html分扎,所以下面就不用再寫了,寫上去也不會(huì)有問(wèn)題胧洒,但是會(huì)有一個(gè)warn畏吓。
gzip_types text/plain application/x-javascript application/javascript text/javascript text/xml text/css;
#選擇支持vary header,可以讓前端的緩存服務(wù)器緩存經(jīng)過(guò)gzip壓縮的頁(yè)面;
gzip_vary on;
root /opt/nginx/html;
index index.html;;
}
#網(wǎng)關(guān)(請(qǐng)求跨域配置)
location ^~/micro-service-api/ {
proxy_pass http://8.135.1.141:10156/;
#允許的請(qǐng)求頭
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í)候頁(yè)面的路徑是localhost,無(wú)法直接獲取到請(qǐng)求的真實(shí)地址無(wú)法更好的調(diào)試
后端跨域配置:當(dāng)沒(méi)有服務(wù)沒(méi)有上nginx服務(wù)器上時(shí)使用-->dev,prod環(huán)境都可以使用菲饼;
nginx跨域配置(推薦):對(duì)原有的開發(fā)代碼無(wú)侵入性肾砂,且效率較高,特別是nginx的壓縮配置極大的提高了頁(yè)面首次的加載速度-->dev,prod宏悦;
這邊建議:配置跨域順序:nginx->后端(網(wǎng)關(guān)->服務(wù))->web
nginx,后端镐确,web 配置跨域只能配置一端,不然瀏覽器會(huì)報(bào)多個(gè)跨域頭的問(wèn)題