当我们在本地开发时,有可能会遇到访问接口存在跨域的情况,如果你的工程是使用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)
}
})
}