最近經常遇到跨域的問題,有時候問題雖然解決了,但是還是會有些模棱兩可概念不清,於是在網上看了一些教程結合實際使用,做個筆記。
1.跨域原因
- 瀏覽器的限制
- 跨域(協議/域名/端口的不同)
- XMLHttpRequest請求
2.解決方案
-
- 瀏覽器禁止檢查(適用於本地寫demo調試)
-
- 后端代碼設置請求參數,允許跨域
-
- 前端不發送XMLHttpRequest請求(如使用
JSONP)
- 前端不發送XMLHttpRequest請求(如使用
-
- 前端使用代理轉發的形式
本篇主要介紹如何使用nginx和proxyTable代理的方式解決前端跨域問題
3.proxyTable
案例:假設我們現在本地的開發地址是http://localhost:8080,請求的地址是:http://localhost:8888/static/cnWord.json,我們在代碼中寫出請求如下:
axios.get('http://localhost:8888/static/cnWord.json').then((res)=>{
console.log('success')
}).catch((res)=>{
console.log('error')
})
因為端口號的不同,運行結果報了跨域的錯誤

下面介紹如何使用proxyTable(基於vue-cli項目中自帶的服務器配置),解決問題,方便開發環境的調試,文件位置:

我們給proxyTable加上配置:
proxyTable: {
'/api': {
target: 'http://localhost:8888',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
target:接口的域名,這里不能直接寫成'http://localhost:8888/static/cnWord.json',親測無效~changeOrigin:開啟代理pathRewrite:可以看到我使用了/api來匹配請求接口的域名,而接口名稱是/static/cnWord.json,因此在實際請求中應該寫成/api/static/cnWord.json,但是我實際請求的地址又是沒有api前綴的,因此需要通過pathRewrite重寫地址,將接口請求的時候前綴去除。
注意修改備注后,需要重新使用
npm run dev打包編譯項目使配置生效
更改請求:
axios.get('/api/static/cnWord.json',).then((res)=>{
console.log('success')
}).catch((res)=>{
console.log('error')
})
此刻控制台打印出

跨域成功!
4.Nginx
上面的方式可以解決我們在vue項目中開發環境的跨域問題,但是無法解決生產環境上的跨域問題,有的時候生產環境上也需要處理跨域問題,這個時候proxyTable就不管用咯,nginx就閃亮登場了~
作用
- 1) http服務器,可以獨立提供http服務;
- 2) 虛擬主機:多個域名指向同一個服務器,服務器根據不同的域名把請求轉發到不同的應用服務器;
- 3) 反向代理:負載均衡,將請求轉發至不同的服務器
安裝與使用
ngixn下載,解壓文件后,啟動命令行開啟web服務器,【注意】nginx的下載包不可放在有中文目錄的文件夾。
start nginx啟動,直接訪問http://localhost/

更多命令:
nginx -s stop快速停止或關閉nginx -s quit正常停止或關閉nginx -s reload修改配置文件后重啟
跨域配置項
解決跨域問題,主要是更改nginx的配置文件nginx.conf,通過配置修改地址的轉發。

// 默認配置
location / {
root html; #文件根目錄
index index.html index.htm; #默認起始頁
}
如此,可以將vue打包后的文件放到nginx的html文件夾中,也可以將root的指向打包后的文件夾,用於快速創建http服務器。還是上面的案例,把proxyTable中的配置全部刪除,然后nginx中增加配置如下:
location / {
root D:\cross-demo\dist #直接指向打包后的文件
index index.html index.htm;
}
location /api/ {
proxy_pass http://localhost:8888/; # 將地址代理到api上
}
訪問http://localhost/ (訪問nginx的http服務)

跨域成功!
虛擬主機配置項
server
{
#監聽端口
listen 80;
#服務訪問域名
server_name localhost;
location /api/ {
# 反向代理的地址
proxy_pass http://localhost:8888/;
# 對發送給客戶端的URL進行修改
proxy_redirect off;
# 后端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 允許客戶端請求的最大單文件字節數
client_max_body_size 10m;
# 緩沖區代理緩沖用戶端請求的最大字節數
client_body_buffer_size 128k;
# 表示使nginx阻止HTTP應答代碼為400或者更高的應答。
proxy_intercept_errors on;
# nginx跟后端服務器連接超時時間
proxy_connect_timeout 90;
# 后端服務器數據回傳超時時間
proxy_send_timeout 90;
# 連接成功后,后端服務器響應超時時間
proxy_read_timeout 90;
# 設置代理服務器(nginx)保存用戶頭信息的緩沖區大小
proxy_buffer_size 4k;
# 設置用於讀取應答(來自被代理服務器)的緩沖區數目和大小
# 默認情況也為分頁大小,根據操作系統的不同可能是4k或者8k
proxy_buffers 4 32k;
# 高負荷下緩沖大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
# 設置在寫入proxy_temp_path時數據的大小,預防一個工作進程在傳遞文件時阻塞太長
proxy_temp_file_write_size 64k;
}
}
}
常見配置
location /api/ {
proxy_pass http://localhost:8888/;
proxy_pass_request_headers on;
proxy_set_header Connection "";
client_max_body_size 30m;
client_body_buffer_size 128k;
proxy_redirect off;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_next_upstream http_502 http_504 error invalid_header;
}
一般情況下,解決前端跨域直接使用這些配置就足夠了,了解各配置項含義,更易於理解。更改location后的轉發代理地址即可。
