vue采坑Axiso解决跨域访问

版权声明:本文版权归Jitwxs所有,欢迎转载,但未经作者同意必须保留原文链接。    https://blog.csdn.net/yuanlaijike/article/details/80522621
源码地址:https://github.com/jitwxs/blog_sample

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

this.$axios.get("http://api.douban.com/v2/movie/top250")
.then(res=>{
    console.log(res)
})
.catch(err=>{
    console.log(err)
})
1
2
3
4
5
6
7
当我们运行程序后,控制台报错如下:

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

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/>'
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
关键代码是:Axios.defaults.baseURL = '/api',这样每次发送请求都会带一个/api的前缀。

Step2:配置代理

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

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


Step3:修改请求Url

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

this.$axios.get("/movie/top250")
.then(res=>{
    console.log(res)
})
.catch(err=>{
    console.log(err)
})
1
2
3
4
5
6
7
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;
    }
     */
}
 

猜你喜欢

转载自blog.csdn.net/weixin_43328237/article/details/85112420