1. 程式人生 > 其它 >vue-cli3開發解決axios跨域問題

vue-cli3開發解決axios跨域問題

目錄

技術概述

本篇部落格主要介紹使用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請求問題解決方案 作者:瑾小瑜