目錄
技術概述
本篇博客主要介紹使用vue-cli3開發時axios跨域問題的解決方法。這個問題是我們小組在進行后台開發涉及到交互部分時遇到的一個大坑,網上雖然有很多的教程,但是有的地方的描述並不是特別的詳細,尤其是url部分的寫法。所以特地寫一篇博客來梳理一下解決流程。希望可以幫助到大家。
技術詳述
此處默認已經搭建好了vue-cli框架。
步驟一:安裝axios。
- 方法一:使用vue ui命令進入可視化界面安裝axios。
@vue/cli3.0增加一個可視化項目管理工具,全局安裝完成cli3.0之后,可以直接在cmd輸入命令:vue ui 啟動即可,地址默認是localhost:8000
如下圖:
接下來點擊安裝依賴
搜索axios
來安裝axios。
- 方法二:使用npm命令
npm install axios --save
安裝axios。如下圖:
步驟二:main.js中引入axios
import axios from 'axios' //引入 axios
Vue.prototype.$axios = axios //把axios掛載到vue的原型中,在vue中每個組件都可以使用axios發送請求
步驟三:在要使用axios請求的頁面引入axios
import axios from "axios";
步驟四:書寫axios請求(以get請求為例)
axios.get('http://xxx.xx.xxx/xxx/xxx',{
params:{
xxx = xxx
}
})
.then(res => {
console.log(res) //查詢成功返回的值
}).catch(error => {
console.log(error) //查詢失敗返回的值
});
你以為的流程:
遇到問題
- 問題一:使用相對路徑寫axios請求。此時會發現請求的url中ip和端口號為前台的ip和端口號。並不是實際上的接口url,所以報錯404。
this.$axios.post(
"/admin/login",
qs.stringify({
account: this.account,
password: this.password,
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}).then((res) => {
console.log(res.data);
//省略具體內容
});
- 問題二:直接使用后端服務器上的接口url。eg:
http://47.106.241.182:8082/admin/login
這導致跨域問題。(雖然使用前端解決了這個問題,但因為在后期后端也使用Spring boot解決了這個問題所以暫時無法復現)
網上偷了張圖代替:
補充說明:
跨域:指ip、端口、協議三者有任意不同則會跨域。
像我們請求的時候本地是http://172.20.84.235:8080/
,后端接口的url是http://47.106.241.182:8082/xxx
,此時ip和端口號不同,則產生了跨域。
解決方法
在
vue.config.js
中設置代理。vue-cli3可能沒有這個文件,那么新建一個就好。配置如下:
module.exports = {
/* 部署生產環境和開發環境下的URL:可對當前環境進行區分,baseUrl 從 Vue CLI 3.3 起已棄用,要使用publicPath */
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
/* 輸出文件目錄:在npm run build時,生成文件的目錄名稱 */
outputDir: 'dist',
/* 放置生成的靜態資源 (js、css、img、fonts) 的 (相對於 outputDir 的) 目錄 */
assetsDir: "assets",
/* 是否在構建生產包時生成 sourceMap 文件,false將提高構建速度 */
productionSourceMap: false,
/* 默認情況下,生成的靜態資源在它們的文件名中包含了 hash 以便更好的控制緩存,你可以通過將這個選項設為 false 來關閉文件名哈希。(false的時候就是讓原來的文件名不改變) */
filenameHashing: false,
/* 代碼保存時進行eslint檢測 */
lintOnSave: true,
/* webpack-dev-server 相關配置 */
devServer: {
/* 自動打開瀏覽器 */
open: false,
port: 8080, //本地端口號
https: false,
hotOnly: false,
/* 使用代理 */
proxy: {
'/api': {
target: 'http://47.106.241.182:8082',//服務器協議、ip和端口號
secure: false, // 如果是https接口,需要配置這個參數
ws: true,//是否代理websockets
changeOrigin: true,
pathRewrite:{
'^/api':''
}
}
},
}
}
重點在於proxy。
- /api:請求的url使用
/api
開始時,才會調用代理。eg:請求url為/api/admin/login
實際對應的請求地址為http://47.106.241.182:8082/api/admin/login
。 - 但我們的請求的接口url可能並不含/api。所以就需要使用
pathRewrite:{ '^/api':'' }
來將url中的/api替換為空。得到正確的請求urlhttp://47.106.241.182:8082/admin/login
- 如果你的請求的所有的url恰好都含有/api,那么可以選擇不寫
pathRewrite
或者寫成pathRewrite:{ '^/api':'/api' }
配置完成后,我們將上面的axios請求改正如下。
this.$axios.post(
"/api/admin/login",//這個地方變了!!!
qs.stringify({
account: this.account,
password: this.password,
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}).then((res) => {
console.log(res.data);
//省略具體內容
});
當我們再次請求就不會顯示跨域了。
實際的流程:
總結
解決axios跨域問題其實並不難,只是我曾經在這上面踩了許許多多的坑。比如:配置了代理,但是在axios請求的時候並沒有寫/api,又或者pathRewrite中自以為的寫成'^/api':'/'等等,導致一直沒有解決。知道各種嘗試解決的那一刻才恍然大悟。希望這篇博客可以對大家有所幫助。
ps:當然也可以讓后端來解決hhh但是前端解決也不麻煩啦。
參考博客
axios解決跨域問題(vue-cli3.0) 作者:累成一條狗
axios處理跨域問題 作者:liutianou
axios請求中跨域及post請求問題解決方案 作者:瑾小瑜