Vue + Nodejs + Express 解决跨域的问题
首先检测你的Vue的版本号
此文章针对3.0版本解决跨域问题
$ vue -V
2.X or 3.X
直接访问如下
created() {
this.$axios.get('http://localhost:3000/users').then(res => {
this.list = res.data.data;
console.log(this.list)
}).catch(err => {
console.log(err)
})
}
但是会出现如下的报错
因为我们跨域,浏览器拦截了我们的请求,下面是解决跨域的办法
1.配置BaseUrl
首先在main.js中,配置下我们访问的Url前缀:
import App from './App.vue'
import router from './router'
import store from './store'
import Vant from 'vant';
import 'vant/lib/index.css';
import axios from 'axios'
Vue.use(Vant);
Vue.config.productionTip = false;
Vue.prototype.$axios = axios;
//
axios.defaults.baseURL = '/users';
axios.defaults.headers.post['Content-Type'] = 'application/json';
//
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
关键代码是:Axios.defaults.baseURL = ‘/api’,这样每次发送请求都会带一个/api的前缀.
2.配置代理
在 package.json 文件的同级目录下创建 vue.config.js 文件。给出该文件的基础配置:
module.exports = {
outputDir: 'dist', //build输出目录
assetsDir: 'assets', //静态资源目录(js, css, img)
lintOnSave: false, //是否开启eslint
devServer: {
open: true, //是否自动弹出浏览器页面
host: "localhost",
port: '8081',
https: false, //是否使用https协议
hotOnly: false, //是否开启热更新
proxy: null,
}
}
修改 vue.config.js 中 devServer 子节点内容,添加一个 proxy:
devServer: {
open: true, //是否自动弹出浏览器页面
host: "localhost",
port: '8080',
https: false,
hotOnly: false,
proxy: {
'/users': {
target: 'http://localhost:3000/users', //API服务器的地址
changeOrigin: true,
pathRewrite: {
'^/users': ''
}
}
},
3.修改请求Url
修改刚刚的axios请求,把url修改如下:
created() {
this.$axios.get('/show').then(res => {
this.list = res.data.data;
console.log(this.list)
}).catch(err => {
console.log(err)
})
}
4.重启服务
重启服务后就可以正常的访问了
5.番外
当然,跨域问题也可以由后端解决,将下面这个过滤器加入程序即可。
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;
}
*/
}