Axiso 解决跨域访问

这里以访问豆瓣Top250为例,直接访问如下:

1
2
3
4
5
6
7
this.$axios.get("http://api.douban.com/v2/movie/top250")
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})

当我们运行程序后,控制台报错如下:

跨域访问错误

可以看到浏览器拦截了我们的请求,因为我们跨域了,下面解决跨域问题。

一、配置 BaseUrl

源码地址:https://github.com/jitwxs/blog_sample

main.js中,配置下我们访问的Url前缀:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的前缀。

二、配置代理

修改config文件夹下的index.js文件,在proxyTable中加上如下代码:

1
2
3
4
5
6
7
'/api':{
target: "http://api.douban.com/v2",
changeOrigin:true,
pathRewrite:{
'^/api':''
}
}

配置代理

三、修改请求 Url

修改刚刚的axios请求,把url修改如下:

1
2
3
4
5
6
7
this.$axios.get("/movie/top250")
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})

四、重启服务

重启服务后,此时已经能够访问了:

豆瓣Top250

五、基本原理

因为我们给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

六、番外

当然,跨域问题也可以由后端解决,将下面这个过滤器加入程序即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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;
}
*/
}
# 跨域

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×