这里以访问豆瓣Top250为例,直接访问如下:
this.$axios.get("http://api.douban.com/v2/movie/top250")
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
当我们运行程序后,控制台报错如下:
可以看到浏览器拦截了我们的请求,因为我们跨域了,下面解决跨域问题。
Step1:配置BaseUrl
在main.js
中,配置下我们访问的Url
前缀:
import Vue from 'vue'
import App from './App'
import Axios from 'axios'
Vue.prototype.$axios = Axios
Axios.defaults.baseURL = '/api'
Axios.defaults.headers.post['Content-Type'] = 'application/json';
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
关键代码是:Axios.defaults.baseURL = '/api'
,这样每次发送请求都会带一个/api
的前缀。
Step2:配置代理
修改config
文件夹下的index.js
文件,在proxyTable
中加上如下代码:
'/api':{
target: "http://api.douban.com/v2",
changeOrigin:true,
pathRewrite:{
'^/api':''
}
}
Step3:修改请求Url
修改刚刚的axios
请求,把url
修改如下:
this.$axios.get("/movie/top250")
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
Step4:重启服务
重启服务后,此时已经能够访问了:
原理:
因为我们给url
加上了前缀/api
,我们访问/movie/top250
就当于访问了:localhost:8080/api/movie/top250
(其中localhost:8080
是默认的IP
和端口)。
在index.js
中的proxyTable
中拦截了/api
,并把/api
及其前面的所有替换成了target
中的内容,因此实际访问Url
是http://api.douban.com/v2/movie/top250。
番外:
当然,跨域问题也可以由后端解决,将下面这个过滤器加入程序即可
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 跨域过滤器
* @author jitwxs
* @since 2018/10/16 20:53
*/
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
// 不使用*,自动适配跨域域名,避免携带Cookie时失效
String origin = request.getHeader("Origin");
if(StringUtils.isNotBlank(origin)) {
response.setHeader("Access-Control-Allow-Origin", origin);
}
// 自适应所有自定义头
String headers = request.getHeader("Access-Control-Request-Headers");
if(StringUtils.isNotBlank(headers)) {
response.setHeader("Access-Control-Allow-Headers", headers);
response.setHeader("Access-Control-Expose-Headers", headers);
}
// 允许跨域的请求方法类型
response.setHeader("Access-Control-Allow-Methods", "*");
// 预检命令(OPTIONS)缓存时间,单位:秒
response.setHeader("Access-Control-Max-Age", "3600");
// 明确许可客户端发送Cookie,不允许删除字段即可
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
/*
注册过滤器:
@Bean
public FilterRegistrationBean registerFilter() {
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
bean.addUrlPatterns("/*");
bean.setFilter(new CorsFilter());
// 过滤顺序,从小到大依次过滤
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
*/
}
webpack之proxyTable设置跨域
1、为什么要使用proxyTable
在平时项目的开发环境中,经常会遇到跨域的问题,尤其是使用vue-cli这种脚手架工具开发时,由于项目本身启动本地服务是需要占用一个端口的,所以必然会产生跨域的问题。当然跨域有多种解决方式,这里就不一一例举,下次弄篇文章单独讲,在使用webpack做构建工具的项目中使用proxyTable代理实现跨域是一种比较方便的选择。
2、还是拿之前使用过的vue-cli举例。我们首先要在项目目录中找到根目录下config文件夹下的index.js文件。由于我们是在开发环境下使用,自然而然是要配置在dev里面:
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://www.abc.com', //目标接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api': '/api' //重写接口
}
},
cssSourceMap: false
}
上面这段代码的效果就是将本地8080
端口的一个请求代理到了http://www.abc.com
这一域名下:
‘
http://localhost:8080/api
’ ===> ‘http://www.abc.com/api
’
没有统一项目名下的使用:
上面那种情况是有一个统一的项目名api的,所以说是比较好匹配的,就相当于说直接将以api开头的接口名代理一下换成目标域名访问就好了,可是如果说后台返给我们前端的接口没有了统一的项目名呢?之前,我是一个个单独去做了转换,接口少还没什么关系,但多了肯定是不现实的,前段时间在一次面试中受到了面试官的启发想到了这样一种取巧的方案:
//先人为给接口地址前面加上一个自定义的项目名
let someApi = 'api' + '/xx/xx';
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://www.abc.com', //目标接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api': '/' //重写接口
}
},
cssSourceMap: false
}
这里的项目名api是我们人为加上去的,经过代理之后就没了,这样我们在配置代理这里还是只需要配置一份就够了,只是在写接口地址时要注意区分开发环境和线上环境就可以了。
原文:https://blog.csdn.net/yuanlaijike/article/details/80522621
https://www.cnblogs.com/wancheng7/p/8987694.html#4281029