什么是跨域?
世界上本沒(méi)有跨域。
瀏覽器有一個(gè)叫做同源策略的東西。同源策略限制了從同一個(gè)源加載的文檔或腳本如何與來(lái)自另一個(gè)源的資源進(jìn)行交互。這是一個(gè)用于隔離潛在惡意文件的重要安全機(jī)制。
同源策略規(guī)定了如果兩個(gè)頁(yè)面的協(xié)議、域名、端口中任意一個(gè)不相等,就認(rèn)為兩個(gè)頁(yè)面具有不相同的源
兩個(gè)不同源的頁(yè)面資源交互會(huì)受到瀏覽器的同源策略限制,也就出現(xiàn)了我們說(shuō)的跨域問(wèn)題
配置proxyTable解決跨域問(wèn)題
我們使用vue-cli生成的項(xiàng)目目錄里,config下面的index.js有個(gè)proxyTable屬性
然后我們做如下設(shè)置
proxyTable: {
// 這里可以理解為使用"/api" 代替 "target" 里的地址,
// 比如說(shuō)我們要調(diào)用的地址是 http://www.example.com/api/list, 則寫(xiě)成 /api/list 就可以了
'/api': {
target: 'http://www.example.com', // 你請(qǐng)求的api地址
secure: false, // 如果是https接口,需要配置這個(gè)參數(shù)
changeOrigin: true //這個(gè)參數(shù)是用來(lái)回避跨站問(wèn)題的,配置完之后發(fā)請(qǐng)求時(shí)會(huì)自動(dòng)修改http header里面的host
}
},
注意以上配置只在開(kāi)發(fā)環(huán)境起作用
webpack-dev-server更加詳細(xì)的配置: https://webpack.js.org/configuration/dev-server/#devserver-proxy
那么為什么我們?cè)O(shè)置這個(gè)proxyTable可以幫我們解決跨域問(wèn)題呢?
其實(shí)vue-cli里的這個(gè)設(shè)置來(lái)自于其集成的插件 http-proxy-middleware
github: https://github.com/chimurai/http-proxy-middleware
這個(gè)插件可以幫我們?cè)诒镜靥摂M一個(gè)服務(wù)器接收請(qǐng)求并代替你發(fā)送該請(qǐng)求,因?yàn)槭窃诜?wù)端替我們發(fā)請(qǐng)求所以就沒(méi)有我們煩惱的跨域問(wèn)題了,當(dāng)然這只適用于開(kāi)發(fā)環(huán)境。
項(xiàng)目上線怎么辦?
我們通過(guò)配置proxyTable解決了本地開(kāi)發(fā)環(huán)境請(qǐng)求接口跨域的問(wèn)題,但是我們項(xiàng)目上線還是要替換成線上的接口地址的。如果我們的前端項(xiàng)目合后端服務(wù)不在同一個(gè)域名下,我們可以使用目前比較流行的 CORS 來(lái)處理跨域。這里就不展開(kāi)講了。
我們可以利用webpack配置的環(huán)境變量來(lái)實(shí)現(xiàn)開(kāi)發(fā)環(huán)境和打包后的api區(qū)分
假設(shè)我們使用axios進(jìn)行請(qǐng)求發(fā)送
我們可以做如下配置
import axios from 'axios';
const config = {
timeout: 60000,
withCredentials: true // 訪問(wèn)線上api時(shí)axios發(fā)送跨域請(qǐng)求時(shí)需要設(shè)置這個(gè)參數(shù)
}
if(process.env.NODE_ENV === 'development') {
// 開(kāi)發(fā)環(huán)境
} else if(process.env.NODE_ENV === 'production') {
// 生產(chǎn)環(huán)境
config.baseURL = "http://www.baidu.com"; //這里是線上api請(qǐng)求地址
}
const server = axios.create(config);
這樣配置后我們開(kāi)發(fā)環(huán)境中就可以使用proxyTable代理請(qǐng)求,項(xiàng)目打包后請(qǐng)求地址就會(huì)被替換成線上的api地址。
假設(shè)我們開(kāi)發(fā)環(huán)境請(qǐng)求的api地址為 http://www.example.com/api/list
線上環(huán)境請(qǐng)求的api地址為 http://www.baidu.com/api/list
那么我們發(fā)請(qǐng)求的時(shí)候只需要這么寫(xiě)
server.get("/api/list").then(res => {
...
})
這樣我們項(xiàng)目打包后,webpack就可以自動(dòng)幫我們把請(qǐng)求地址替換成線上的地址了。