Vue 3.x+axios跨域方案的踩坑指南
緣起
最近實(shí)驗(yàn)課上需要重構(gòu)以前寫過的一個(gè)項(xiàng)目(垃圾堆),需要添加發(fā)生郵件提醒的功能,記得以前寫過一個(gè)PHP版的實(shí)現(xiàn),所以想把PHP寫的功能整理成一個(gè)服務(wù),然后在前端調(diào)用。但是這個(gè)項(xiàng)目是JavaWeb,也就是說我需要面對跨域的問題。不過本篇文章,講的并不是如何解決這樣的跨域問題,而是我在找如何解決這個(gè)問題的路上遇到的坑。
其實(shí),在前端工程化大行其道的現(xiàn)在,前后端已經(jīng)分離開來,前端為了提高工作流效率往往自己開一個(gè)小型的服務(wù)器,就比如webpack.devServer。這樣在前端調(diào)用后端接口的時(shí)候必然會(huì)面臨跨域的問題,
如題,Vue3.x + axios 跨域方案 就是解決這里的跨域問題。這里的跨域是基于webpack的devServer的代理功能(proxy)來實(shí)現(xiàn)開發(fā)環(huán)境中的跨域,也就是說本篇所討論的并不能解決生產(chǎn)環(huán)境下的跨域問題,因?yàn)閣ebpack.devServer是DevDependencies,一旦打包上線,這個(gè)proxy代理就會(huì)失效。但是這并不妨礙我們開發(fā)中使用跨域來提高開發(fā)效率和體驗(yàn)。
開始填坑
其實(shí)這個(gè)問題解決起來很簡單,網(wǎng)上也是很多教程,為了文章完整性,我這里也做一個(gè)盡量完備的展示,介紹如何配置Vue3.x來實(shí)現(xiàn)跨域 。
vue.config.js中devServer.proxy的配置解析
Vue3.x的CLI工具比Vue2.x的CLI工具構(gòu)建的項(xiàng)目要簡化很多,根目錄下只有./src和./public文件夾,所以網(wǎng)上很多教程說config目錄下的vue.config.js是說的vue2.x版本。那么對于Vue3.x版本,構(gòu)建也很簡單,直接在根目錄里建一個(gè)vue.config.js配置文件就可以了,我們直接看devServer.proxy里的代碼:
我這里devServer的地址是:localhost:8080/,需要代理的地址是:localhost/index/phpinfo.php (我自己寫的一個(gè)測試跨域用的php,返回一個(gè)‘ok')
下面是根據(jù)上面的地址需要配置的proxy對象
devServer : { proxy : { '/index' : { target : 'http://localhost/index', // ws : true, changeOrigin : true, pathRewrite : { '^/index' : '' } } } }
大部分教程到這里就停止了,但是我在這里做一個(gè)擴(kuò)展,為了讓讀者理解這里的配置是如何起作用的(以下內(nèi)容整理自http-proxy-middleware的npm描述里,http-proxy-middleware是一個(gè)npm模塊,是proxy的底層原理實(shí)現(xiàn))。
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
以我上面的配置為例,'/index'這個(gè)key在http-proxy-middleware中被稱為context——用來決定哪些請求需要被target對應(yīng)的主機(jī)地址(這里是http://localhost/index)代理,它可以是 字符串,含有通配符的字符串,或是一個(gè)數(shù)組,分別對應(yīng)于path matching(路徑匹配)wildcard path matching(通配符路徑匹配)multiple path matching(多路徑匹配),而這里的path指的就是上圖所標(biāo)識的path段。
簡言之,這個(gè)key就是匹配path的,一旦匹配到符合的path,就會(huì)把請求轉(zhuǎn)發(fā)的代理主機(jī)去,而代理主機(jī)的地址就是target字段對應(yīng)的內(nèi)容。
那pathRewrit是什么意思呢?意如其名,路徑重寫。就是把模式(這里是^/index)匹配到的path重寫為對應(yīng)的路徑(這里是'',相當(dāng)于刪除了這個(gè)匹配到的路徑)。除了刪除,還有在原有路徑上添加一個(gè)基礎(chǔ)路徑,或是改寫一個(gè)路徑的方式,這可以參考http-proxy-middleware的npm描述的option.pathRewrite章節(jié) 。
在Vue中使用axios
這個(gè)使用任意一個(gè)ajax封裝的庫都是可行的,axios,jquery.ajax或者是vue-resource都是可以的。
在Vue中使用axios,網(wǎng)上有兩種方法,一種是將axios加入Vue的原型里,我更推薦第二種方法:
npm install axios vue-axios
import axios from 'axios'; import VueAxios from 'vue-axios'; Vue.use(VueAxios,axios);
以我上面的proxy配置為基礎(chǔ),想要讓代理成功轉(zhuǎn)發(fā)到localhost/index/phpinfo.php,在Vue實(shí)例中axios需要這樣寫訪問地址:
this.axios.get('/index/phpinfo.php').then((res)=>{ console.log(res); })
我們來分析這些代碼整個(gè)發(fā)揮作用的原理是什么?首先,axios去訪問/index/phpinfo.php,這是個(gè)相對地址,所以真實(shí)訪問地址其實(shí)是localhost:8080/index/phpinfo.php,然而/index/phpinfo.php被我們配置的/index匹配到了 ,所以訪問被proxy代理,那轉(zhuǎn)發(fā)到哪個(gè)路徑呢?在pathRewrite中,我們將模式^/index的路徑清除了,所以最終的訪問路徑是 target+pathRewrite+ 剩余的部分 , 這樣也就是 http://localhost/index++/phpinfo.php
坑點(diǎn)
可能出現(xiàn)即使配置了proxy,但是依然沒有任何卵用。
- 大部分情況是因?yàn)槟愕膒roxy配置和你的訪問路徑不匹配,或者即使匹配到了,但是轉(zhuǎn)發(fā)出去的地址不對,沒有命中后端給的API
- 或者看看axios,有沒有使用正確姿勢?
- 還有一點(diǎn),或許你看到返回的response里的url依然顯示的是本地主機(jī),但是數(shù)據(jù)已經(jīng)正常返回,這是正常的,因?yàn)槲覀冊L問的本來就是本地主機(jī),只不過proxy轉(zhuǎn)發(fā)了這個(gè)請求到一個(gè)新的地址。
后續(xù)
本篇只解決了開發(fā)環(huán)境下的跨域問題,實(shí)際線上還不能跨域,目前這里有一些方案:
- Nginx反向代理跨域
- JSONP
- CORS
下一次討論這個(gè)跨域問題,嘗試解決。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
Vue解決element-ui消息提示$message重疊問題
這篇文章主要為大家介紹了Vue解決element-ui消息提示$message重疊問題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08解決vue 使用setTimeout,離開當(dāng)前路由setTimeout未銷毀的問題
這篇文章主要介紹了解決vue 使用setTimeout,離開當(dāng)前路由setTimeout未銷毀的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07vue.js的狀態(tài)管理vuex中store的使用詳解
今天小編就為大家分享一篇vue.js的狀態(tài)管理vuex中store的使用詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11vue實(shí)現(xiàn)的微信機(jī)器人聊天功能案例【附源碼下載】
這篇文章主要介紹了vue實(shí)現(xiàn)的微信機(jī)器人聊天功能,結(jié)合實(shí)例形式分析了基于vue.js的微信機(jī)器人聊天相關(guān)界面布局、ajax交互等操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2019-02-02element-ui table行點(diǎn)擊獲取行索引(index)并利用索引更換行順序
這篇文章主要介紹了element-ui table行點(diǎn)擊獲取行索引(index)并利用索引更換行順序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02淺談VueUse中useAsyncState的實(shí)現(xiàn)原理
useAsyncState?是 VueUse 庫中提供的一個(gè)實(shí)用工具,它用于處理異步狀態(tài),本文主要介紹了VueUse中useAsyncState的實(shí)現(xiàn)及其原理,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08Vues中使用JavaScript實(shí)現(xiàn)路由跳轉(zhuǎn)的步驟詳解
在Vue應(yīng)用中,利用Vue?Router進(jìn)行頁面間的導(dǎo)航是一個(gè)常見需求,本篇博客將通過示例代碼詳細(xì)介紹如何在Vue組件中使用JavaScript實(shí)現(xiàn)路由跳轉(zhuǎn),需要的朋友可以參考下2024-05-05