Vue中的开发环境跨域问题
前言
- 什么是跨域?
简单来说就是有上图这样的问题出现,控制台报错。
为什么会出现跨域?
受到浏览器的同源策略限制,浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。
跨域问题主要分出现在开发环境(本地运行)中的跨域,以及生产环境(部署于线上的环境)中的跨域
开发环境(即本地运行)
在Vue2.0中
- 先配置好axios的baseURL,即下面代码段中的 axios.defaults.baseURL = ‘/api/‘,作用是我们每次发送的请求都会带一个/api/的前缀。这段代码可以写在main.js中,也可以写在一个request.js的文件中单独作为axios的配置文件,方便维护。
1 | // 配置请求的根路径 |
- 配置代理,(配置在vue.config.js文件中的proxyTable字段中)
1 | module.exports = { |
- target后面的就是需要请求的网址的公共部分,然后用
/apis
来代理这个,最后重写一些路径,请求的时候使用的我们的代理的apis来作为前缀。
- 简单来说,就是用
/apis
来代替前面要跨域的接口网站,比如上面要跨域的网站域名是http://localhost:8080/,那么这个`/apis`就是代替它的别称,就是换了个名字而已,但是它起到了代理的作用,可以实现跨域请求。
在Vue3.0中
vue-cli3 脚手架搭建完成后,项目目录中没有 vue.config.js 文件,需要手动创建
新建一个vue.config.js,配置以下信息,同样可以解决。
1
2
3
4
5
6
7
8
9
10
11
12
13
14module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'http://localhost:8080/',//接口的前缀
ws:true,//代理websocked
changeOrigin:true,//虚拟的站点需要更管origin
pathRewrite:{
'^/api':''//重写路径
}
}
}
}
}
小结
changeOrigin: true :开启代理:在本地会创建一个虚假服务器,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端就可以进行数据的交互。
apis
就是接口实际请求的前缀,去代理了我们的实际的接口前缀的公共部分比如 请求接口为
localhost:8080/getData
我们只需要传入:getData
withCredentials属性
- 最近在开发调试的过程出现了跨域的另一种情况
- The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’.
对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“”。这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。
也就是说
Access-Control-Allow-Credentials
设置为true
的情况下Access-Control-Allow-Origin
不能设置为*
ps: 关于指定域名 可以在后端用个
array
类似的存一个白名单域名列表
如果有请求 先判断Origin
是否在白名单里 然后再动态设置Access-Control-Allow-Origin
前端的解决办法就是将withCredentials属性设为false即可
1 | const service = axios.create({ |
- 我的项目是不需要cookie的,如果项目需要携带cookie的话,那么是要后端配置的。
SpringBoot解决跨域问题
方案1
在Spring Boot 中给我们提供了一个注解 @CrossOrigin 来实现跨域,这个注解可以实现方法级别的细粒度的跨域控制。
我们可以在类或者方添加该注解,如果在类上添加该注解,该类下的所有接口都可以通过跨域访问,如果在方法上添加注解,那么仅仅只限于加注解的方法可以访问。
示例:
1 |
|
方案2
在Springboot项目里加上这个配置文件CorsConfig.java
,重启之后即可实现跨域访问,前端无需再配置跨域。
1 | import org.springframework.context.annotation.Bean; |