vue前端跨域問題


一、跨域分類
  跨域分為開發跨域(開發環境跨域)和線上跨域(生產環境跨域):

  • 開發環境跨域:開發階段前后端工作站不同,所以ip地址不同,請求數據必然出現跨域問題;
  • 生產環境跨域:一個網站關聯多台服務器產生的跨域問題,構成一個完整的生產服務器集群,生產服務器集群之間的通信通過地址的方式通信,就算在局域網中,端口地址也是不一樣的。

二、解決
2.1 線上跨域
  線上跨域的常規解決方案:

  • 后端代碼上增加一個跨域請求響應頭:Access-Control-Allow-Origin

   例如:php中的header(Access-Control-Allow-Origin:*)     ;PS:其中,*表示所有請求地址都可允許跨域響應

  • 也可以采用 前后端配置處理 的方式:采用jsonp模式,前端完成jsonp請求發送

2.2 開發跨域

  即:在開發過程中存在的跨域問題,這種現象一般出現在 前后端分離的項目中:前后端分離導致開發聯調過程中不在同一服務器或端口下,引發的跨域。

  開發階段引發的跨域可能在項目上線時消失,即當前端代碼打包到后端同一服務器上,此時地址相同端口相同,相當於所有的接口都是在同一服務器內部進行請求調用操作,因此便不會產生跨域。但是呢,沒有開發哪兒來的上線,因此還是免不了開發過程中的跨域。

  解決方式:前端構建代理服務器來完成跨域。即:在本地創建一個虛擬服務器,發送請求數據,同時接收請求的數據

  過程:

  1.  在vue.config.js配置文件中,通過devServer.proxy選項配置代理:
    devServer:{
      port: 8080,
      proxy: {
          // key:描述項目中哪些請求需要被代理服務器代理,以路徑前綴方式描述key,定義被攔截請求的前綴
          "/api": {
              target: "http://127.0.0.1:8080", // 定義被攔截的請求需要訪問的真實服務器
              pathRewrite: { // 通過前綴替換進行地址的重寫和定義:去掉/api(因為/api默認會拼接上去)
                "^/api": "" // 替換掉以/api開頭的,這里用空字符串替換,直接去掉
              }
          }
      }
    }

    原理:當遇到“/api”時,會進入內部函數,將target變量的真實后台地址拼接到“/api”的前面,此時 請求路徑變成了:“http://127.0.0.1:8080/api",然后由於pathRewrite方法中將 “/api”替換成了空,也就是說直接去掉,因此路徑變成了 ““http://127.0.0.1:8080”,這就完成了代理,通過“/api”這個橋梁將后台地址成功地引入。

    注:
    vue.config.js文件只是做前端代理解決跨域問題時所用到的配置文件,當前端打包到服務器上時,該文件會被忽略,因此前端對於 api接口路徑的定義一定要跟后端所提供的保持一致,不能隨意增減上下文,即使你可能通過 配置代理 獲取了正確的請求路徑,因為打包到服務器后代理便失效了。

三、實例

1、當前需請求的后端接口路徑:

192.168.88.88:8091/host/getHostsInfo

2、配置文件

devServer:{
  port: 8080,    //代表本地服務器啟動后的虛擬端口
  proxy: {
      "^/host": {    // ^/host 表示匹配查詢以host開頭的路徑, /host有可能查詢到路徑中包含host的,不一定作為開頭
          target: "http://192.168.88.88:8091", // 定義被攔截的請求需要訪問的真實服務器
          pathRewrite: { // 通過前綴替換進行地址的重寫和定義:去掉/host(因為/host默認會拼接上去)
            "^/host": "/host" // 替換掉以/host開頭的,這里只是為了展示pathRewrite的用法,不需替換可以直接去掉這段。
          }
      }
  }
}

 3、創建axios的時候,baseUrl配置:

const ajax = axios.create({
    baseURL:"",
    timeout: 6000,//請求超時時間
})

創建請求:

export function getData() { //get
  return request({
    url: '/host/getHostsInfo',
    method: 'GET'
  })
}

此時,baseUrl拼上請求地址,得到:/host/getHostsInfo,在代理proxy函數中,遇到 /host,則代理到target下的真實服務器路徑,將target的真實服務器地址加到 /host 前面,因此得到:http://192.168.88.88:8091/host/getHostsInfo ,也就是真實需請求的后端真實服務器接口路徑地址。

而如果在pathRewrite中對路徑進行了重寫,將 /host 替換成 "" 空字符串,即去掉它,此時代表后端接口請求路徑:http://192.168.88.88:8091/getHostsInfo。當然,本實例中這樣的代理是調不通的~

 

四、當項目需請求不同的后端地址時候,可配置多個代理。

原理一樣,直接上代碼:

    proxy:{
      "/api": {
          target: "http://192.168.88.88:8091", 
          // ws: true, // 是否啟用websockets
          changeOrigin: true
          pathRewrite: {
              "^/api": ""
          }
      },
      "/user": {
          target: "http://192.168.99.99:8091",
          // ws: true, 
          changeOrigin: true
          pathRewrite: {
              "^/user": ""
          }
      },
   
  }, 

baseUrl配置:

const ajax = axios.create({
    baseURL:"/",    //注意:這里我baseUrl寫的是 / ,因此在請求接口里的url沒有以 / 開頭了,寫法隨意,原理就是一個拼接過程。
    timeout: 6000,//請求超時時間
})

請求接口:

export function getData() { //get
  return request({
    url: 'api/host/getHostsInfo',
    method: 'GET'
  })
}
export function getData1() { //get
  return request({
    url: 'user/host/getHostsInfo',
    method: 'GET'
  })
}

此時,上面兩種方式最終請求的真實服務器接口路徑 是 兩台服務器下的同一接口路徑:

http://192.168.88.88:8091/host/getHostsInfo
http://192.168.99.99:8091/host/getHostsInfo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM