最近實驗課上須要重構之前寫過的一個項目(垃圾堆),須要添加發生郵件提醒的功能,記得之前寫過一個PHP版的實現,因此想把PHP寫的功能整理成一個服務,而後在前端調用。可是這個項目是JavaWeb,也就是說我須要面對跨域的問題。不過本篇文章,講的並非如何解決這樣的跨域問題,而是我在找如何解決這個問題的路上遇到的坑。javascript
其實,在前端工程化大行其道的如今,先後端已經分離開來,前端爲了提升工做流效率每每本身開一個小型的服務器,就好比webpack.devServer
。這樣在前端調用後端接口的時候必然會面臨跨域的問題, 如題,Vue-cli 3.x + axios 跨域方案
就是解決這裏的跨域問題。這裏的跨域是基於webpack
的devServer的代理功能(proxy)來實現開發環境中的跨域,也就是說本篇所討論的並不能解決生產環境下的跨域問題,由於webpack.devServer是DevDependencies,一旦打包上線,這個proxy代理就會失效。可是這並不妨礙咱們開發中使用跨域來提升開發效率和體驗。php
其實這個問題解決起來很簡單,網上也是不少教程,爲了文章完整性,我這裏也作一個儘可能完備的展現,介紹如何配置Vue-cli 3.x來實現跨域 。前端
Vue-cli3.x比Vue-cli2.x構建的項目要簡化不少,根目錄下只有./src
和./public
文件夾,因此網上不少教程說config
目錄下的vue.config.js
是說的vue-cli 2.x版本。那麼對於Vue-cli 3.x版本,構建也很簡單,直接在根目錄裏建一個vue.config.js
配置文件就能夠了,咱們直接看devServer.proxy
裏的代碼:vue
我這裏devServer的地址是:localhost:8080/,須要代理的地址是:localhost/index/phpinfo.php (我本身寫的一個測試跨域用的php,返回一個‘ok’)java
下面是根據上面的地址須要配置的proxy對象jquery
devServer : {
proxy : {
'/index' : {
target : 'http://localhost/index',
// ws : true,
changeOrigin : true,
pathRewrite : {
'^/index' : ''
}
}
}
}
複製代碼
大部分教程到這裏就中止了,可是我在這裏作一個擴展,爲了讓讀者理解這裏的配置是如何起做用的(如下內容整理自http-proxy-middleware
的npm描述裏,http-proxy-middleware
是一個npm模塊,是proxy的底層原理實現)。webpack
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
複製代碼
以我上面的配置爲例,'/index'
這個key
在http-proxy-middleware
中被稱爲context
——用來決定哪些請求須要被target
對應的主機地址(這裏是http://localhost/index
)代理,它能夠是 字符串,含有通配符的字符串,或是一個數組,分別對應於path matching
(路徑匹配)wildcard path matching
(通配符路徑匹配)multiple path matching
(多路徑匹配),而這裏的path
指的就是上圖所標識的path段。ios
簡言之,這個key就是匹配path
的,一旦匹配到符合的path
,就會把請求轉發的代理主機去,而代理主機的地址就是target
字段對應的內容。git
那pathRewrit
是什麼意思呢?意如其名,路徑重寫。就是把模式(這裏是^/index
)匹配到的path
重寫爲對應的路徑(這裏是''
,至關於刪除了這個匹配到的路徑)。除了刪除,還有在原有路徑上添加一個基礎路徑,或是改寫一個路徑的方式,這能夠參考http-proxy-middleware
的npm描述的option.pathRewrite章節 。github
這個使用任意一個ajax封裝的庫都是可行的,axios,jquery.ajax或者是vue-resource都是能夠的。
在Vue中使用axios,網上有兩種方法,一種是將axios加入Vue的原型裏,我更推薦第二種方法:
npm install axios vue-axios
複製代碼
import axios from 'axios';
import VueAxios from 'vue-axios';
Vue.use(VueAxios,axios);
複製代碼
以我上面的proxy配置爲基礎,想要讓代理成功轉發到localhost/index/phpinfo.php
,在Vue實例中axios須要這樣寫訪問地址:
this.axios.get('/index/phpinfo.php').then((res)=>{
console.log(res);
})
複製代碼
咱們來分析這些代碼整個發揮做用的原理是什麼?首先,axios去訪問/index/phpinfo.php
,這是個相對地址,因此真實訪問地址實際上是localhost:8080/index/phpinfo.php
,然而/index/phpinfo.php
被咱們配置的/index
匹配到了 ,因此訪問被proxy代理,那轉發到哪一個路徑呢?在pathRewrite
中,咱們將模式^/index
的路徑清除了,因此最終的訪問路徑是 target
+pathRewrite
+ 剩餘的部分 , 這樣也就是 http://localhost/index
++
/phpinfo.php
可能出現即便配置了proxy,可是依然沒有任何卵用。
本篇只解決了開發環境下的跨域問題,實際線上還不能跨域,目前這裏有一些方案:
下一次討論這個跨域問題,嘗試解決。