因为axios中只能使用get和post方法来进行请求数据,没有提供jsonp等方法进行跨域访问数据,所以使用axios发生跨域,可使用以下2种方案。
方案1:既然使用axios直接进行跨域访问不可行,在vue中使用本地代理的方式进行跨域。
代理可以解决的原因:因为客户端请求服务端的数据是存在跨域问题的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念(如果服务器没有设置禁止跨域的权限问题),也就是说,我们可以配置一个代理的服务器可以请求另一个服务器中的数据,然后把请求出来的数据返回到我们的代理服务器中,代理服务器再返回数据给我们的客户端,这样我们就可以实现跨域访问数据。
1.首先在main.js
中,配置下我们访问的Url前缀:这样每次发送请求都会带一个/api
的前缀。
import Vue from 'vue' import App from './App' import router from './router' import axios from 'axios' Vue.prototype.$axios = axios axios.defaults.baseURL = '/api' axios.defaults.headers.post['Content-Type'] = 'application/json'; Vue.config.productionTip = false new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
2.修改 vue.config.js 中 devServer
子节点内容,添加一个 proxy
:
devServer: { open: true, //是否自动弹出浏览器页面 host: "localhost", port: '8080', https: false, hotOnly: false, proxy: { '/api': { target: 'https://www.v2ex.com/api', //API服务器的地址 changeOrigin: true, pathRewrite: { '^/api': '' } } }, }
3.修改url请求:
this.$axios .get("/unit/queryTree") .then(res => { console.log(res.data); }) .catch(err => { console.log(err); });
方案2: 后端处理跨域问题,加个过滤器即可解决,如下:
原理:跨源资源共享标准通过新增一系列 HTTP 头,让服务器来声明哪些来源可以通过浏览器访问该服务器上的资源
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; 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); } }