當我們在本地開發時,有可能會遇到訪問接口存在跨域的情況,如果你的工程是使用webpack工程化編譯打包的話,那麼可以利用webpack 的本地服務器devServer的proxy代理功能實現跨域。
比如你的本地前端工程啓動後的域名是:http://localhost:8080,需要訪問的後臺接口是:http://response.com/mock/demo,直接訪問的話肯定會存在跨域,那麼需要在webpack的配置文件中配置如下:
module.exports = {
entry: {
app: './index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, './dist')
},
mode: 'development',
devtool: 'inline-source-map',
devServer:{
contentBase: './',
hot: true,
publicPath: '/',
host: 'localhost',
// 配置跨域請求
proxy: {
'/mock': {
target: 'http://response.com', //接口實際目標地址
changeOrigin: true //啓動跨域
}
}
}
}
‘/mock’是匹配請求url中的'/mock'字符串,如下面的url中的'http://response.com/mock/demo',此時已經匹配到,直接會把'http://response.com/mock/demo'請求代理至'http://localhost:8080/mock/demo',相當於瀏覽器直接向本地開發服務器請求數據,域名單口都是一樣的,所以就不會有跨域問題
在業務代碼中請求:
function ajaxFn(keywords){
$.ajax({
type: 'GET',
url: `http://response.com/mock/demo`,
async: true,
contentType: 'application/json;charset=utf-8',
success: function(data){
console.log(data)
},
error:function(e){
console.log(e)
}
})
}
還有一種寫法:使用實際url中並不存在的字符串來標記特定的接口進而使用代理。這種寫法適應的場景更多。例子如下:
請求的時候,將接口'http://response.com/mock/demo' 寫成 'http://response.com/testApi/mock/demo',在url中加入‘/testApi’這個字符串來標識這個接口,在webpack的配置文件中就這樣寫:
devServer:{
contentBase: './',
hot: true,
publicPath: '/',
host: 'localhost',
// 配置跨域請求
proxy: {
'^/testApi': {
target: 'http://response.com', //接口實際目標地址
changeOrigin: true //啓動跨域
pathRewrite: {
'^/testApi': '' //由於真實url中不存在/testApi,所以這裏要將此重寫爲空,將它去掉
}
}
}
}
'^/testApi'是一個正則表達式,'^' 表示匹配url字符串是以'/testApi'開始的,當然也可以不加這個 '^' ,那麼只要url中有/testAPI就會匹配到,如下:
devServer:{
contentBase: './',
hot: true,
publicPath: '/',
host: 'localhost',
// 配置跨域請求
proxy: {
'/testApi': {
target: 'http://response.com', //接口實際目標地址
changeOrigin: true //啓動跨域
pathRewrite: {
'/testApi': '' //由於真實url中不存在/testApi,所以這裏要將此重寫爲空,將它去掉
}
}
}
}
由於真實url中不存在/testApi,所以這裏使用pathRewrite屬性將/testApi重寫爲空,將它去掉,所以此時本地代理請求地址還是'http://localhost:8080/testApi/mock/demo',但代理的真實請求地址由原來的'http://response.com/testApi/mock/demo' 變成 了 'http://response.com/mock/demo'。
在業務代碼中請求的寫法如下:
function ajaxFn(){
$.ajax({
type: 'GET',
url: `/testApi/mock/demo`,
// 或 url: `http://response.com/testApi/mock/demo`,
async: true,
contentType: 'application/json;charset=utf-8',
success: function(data){
console.log(data)
},
error:function(e){
console.log(e)
}
})
}
多個接口代理
如果有多個接口需要代理,並且代理的target相同,那麼可以使用devServer的context屬性來實現這個功能
比如:兩個接口http://response.com/mock1/demo、http://response.com/mock2/demo都需要代理,那麼配置文件就可以這樣寫:
devServer:{
contentBase: './',
hot: true,
publicPath: '/',
host: 'localhost',
// 配置跨域請求
proxy: [{
context: ['/mock1', '/mock2'],
target: 'http://response.com'
}]
}
業務請求時,可以寫真實的地址:
function ajaxFn(){
$.ajax({
type: 'GET',
url: `http://response.com/mock1/demo`,
async: true,
contentType: 'application/json;charset=utf-8',
success: function(data){
console.log(data)
},
error:function(e){
console.log(e)
}
})
$.ajax({
type: 'GET',
url: `http://response.com/mock2/demo`,
async: true,
contentType: 'application/json;charset=utf-8',
success: function(data){
console.log(data)
},
error:function(e){
console.log(e)
}
})
}