Vue使用axios及http-proxy-middleware解決跨域存取RESTful APIs問題

前言

由於Vue.Js官方已不在維護vue-resource,而另推薦使用axios。因此就以axios為例,搭配http-proxy-middleware,做到

  1. 跨域存取
  2. 前後端分離的開發,最終部署仍是同一台server的話,也可以讓API網址直接寫成部署後的內部使用樣子,避免部署時需要再修改的網址的雜事

而VUE-CLI產生的專案本身已有先將proxytable寫好了!因此裝好套件設定好後,就可以直接使用了!

安裝axios及http-proxy-middleware

npm i axios --save-dev
npm i vue-axios --save-dev
npm i http-proxy-middleware --save-dev

載入axios

打開src/main.js,輸入

import axios from 'axios';
import VueAxios from 'vue-axios';
Vue.use(VueAxios,axios);

設定http-proxy-middleware

打開config/index.js,搜尋proxyTable,會看到官方已經預置在裡面,將設定填進至{}裡面

proxyTable: {
      '/api': {                        // 前端的變數
        target: 'http://127.0.0.1:8000/api/',  // 遠端或後端提供的連結
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        },
         //可設定多個,用,隔開
      }

app.vue檔新增一個methods測試 (記得template要加個button關聯)

methods: {
 	test(){
    let vm = this;   
    vm.axios.post('/api/user/',{usr:'test',pwd:'pwd'}).then(res=>{
      console.log(res.data);
    });
    //若沒設定http-proxy-middleware,後端有關閉垮域限制供開發使用。則開發時需寫成這樣來取資料
    //但最終又會部署在同一台,導致build檔時還需要再修改地址,很麻煩
    vm.axios.post('http://127.0.0.1:8000/api/user/',{usr:'test',pwd:'pwd'}).then(res=>{
      console.log(res.data);
    });
  }
}

打開chrome的console,會看到順利取得資料

其實他的作業方式也很容易理解

當遇到/api時,在前面加上http://127.0.0.1:8000/api/,但路徑就變成了http://127.0.0.1:8000/api/api了!網址就錯了!

所以接著在pathRewrite裡把原本的關鍵字/api拿掉,這樣在get時得到的網址,就會是http://127.0.0.1:8000/api/user/了!

注意!每次修改proxyTable後,都需要重新啟動服務!!他沒有hot-reload!

即按ctrl+c後在npm run dev

分享一個踩過的坑

若proxyTable路徑很相似的話,他會直接以先取到的為主,然後網址就會解析錯誤啦!

比如以下例子:

proxyTable: {
      '/api': {                        // 前端的變數
        target: 'http://127.0.0.1:8000/api/',  // 遠端或後端提供的連結
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        },
      '/api-auth/': {                        // 前端的變數
        target: 'http://127.0.0.1:8000/api-auth/',  // 遠端或後端提供的連結
        changeOrigin: true,
        pathRewrite: {
          '^/api-auth': ''
        },
      }

會發現得到的網址是http://127.0.0.1:8000/api/-auth/

這個坑最大的問題是在console看到的post網址是正確的,沒注意的話還真的滿不容易發現的…

解決方法很簡單,把每個的後面都加/,讓他完整取代

proxyTable: {
+      '/api/': {                        // 前端的變數
        target: 'http://127.0.0.1:8000/api/',  // 遠端或後端提供的連結
        changeOrigin: true,
        pathRewrite: {
+          '^/api/': ''
        },
+      '/api-auth/': {                        // 前端的變數
        target: 'http://127.0.0.1:8000/api-auth/',  // 遠端或後端提供的連結
        changeOrigin: true,
        pathRewrite: {
+          '^/api-auth/': ''
        },
      }

在Vue.Js寫axios時記得每個網址結尾都要寫好/,如/api/user/,不要偷懶只寫個/api/user,就不太會出現這種錯誤了!

參考資料

如何在 Vue-CLI 建立的開發環境呼叫跨域遠端 RESTful APIs

Github/http-proxy-middleware