如何解決vue專案(cli3以上)中的跨域問題(axios版)
技術標籤:vuejavascript
如何解決vue專案(cli3以上)中的跨域問題(axios版)
今天在寫專案的時候突然網路請求傳送不出去,一看是出現了跨域問題,如下圖。
要想解決這個問題,我們必須先了解什麼是跨域,當然你想直接看解決方法可以直接下滑拉。
什麼是跨域?
跨域,是指瀏覽器不能執行其他網站的指令碼。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript實施的安全限制。
這裡說明一下,無法跨域是瀏覽器對於使用者安全的考慮,如果自己寫個沒有同源策略的瀏覽器,完全不用考慮跨域問題了。是瀏覽器的鍋,對。
同源策略限制了一下行為:
- Cookie、LocalStorage 和 IndexDB 無法讀取
- DOM 和 JS 物件無法獲取
- Ajax請求傳送不出去
什麼是瀏覽器同源策略?
同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說 Web 是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。
它的核心就在於它認為自任何站點裝載的信賴內容是不安全的。當被瀏覽器半信半疑的指令碼執行在沙箱時,它們應該只被允許訪問來自同一站點的資源,而不是那些來自其它站點可能懷有惡意的資源。
所謂同源是指:域名、協議、埠相同。
舉個栗子:如下,相對於http://www.beiebi.cn/home/index.html的同源檢測結果
URL | 結果 | 原因 |
---|---|---|
http://www.beiebi.cn/person/index.html | 成功 | 域名,協議,埠都相同 |
https://www.beiebi.cn/home/index.html | 失敗 | 協議不同 |
http://www.beiebi.cn:8080/home/index.html | 失敗 | 埠不同 |
http://www.beiebi.com/home/index.html | 失敗 | 域名不同 |
如何解決跨域呢?
我們這裡使用的是伺服器代理的方法
瀏覽器有跨域限制,但是伺服器不存在跨域問題,所以可以由伺服器請求所要域的資料再返回給客戶端
我這裡是把axios再度封裝了,
主要的點是baseURL:’/api’,這裡的’/api’可以隨意設定,看自己。
import axios from "axios";
export function http(config) {
// 1.建立axios的例項
const instance = axios.create({
baseURL:'/api',
timeout: 5000,
});
// 2.axios的攔截器
// 2.1.請求攔截的作用
instance.interceptors.request.use(
config => {
return config;
},
err => {
// console.log(err);
}
);
// 2.2.響應攔截
instance.interceptors.response.use(
res => {
// 返回資料
return res.data;
},
err => {
console.log(err);
}
);
// 3.傳送真正的網路請求
return instance(config);
}
然後在vue.config.js配置代理,將你真正想要訪問的域名放在target裡面
module.exports = {
devServer: {
proxy: {
"/api": {
// 此處的寫法,目的是為了 將 /api 替換成 你想要訪問的域名
target: "http://www.beibei.com/home",
// 允許跨域
changeOrigin: true,
pathRewrite: {
"^/api": "",
},
},
},
},
}
然後就可以正常的傳送請求,獲取資料了
我個人比較喜歡封裝,所以會將同一個頁面的網路請求放在同一個js檔案,當我這個頁面需要傳送網路請求時,直接去匯入使用就可以了,下面是首頁的請求。
import {http} from "./http";
// 首頁的網路請求方法
export function getCreative() {
return http({
url: '/home/Creative'
})
}
假如下面是首頁,已經匯入了首頁的請求方法
data() {
return {
list:[]
}
}
mounted() {
// 傳送網路請求
this._getCreative()
},
methods: {
_getCreative() {
getCreative().then(res => {
let list = res.data;
this.list = list;
})
}
}