spring vue 打包后的跨域请求资源(跨域preflight)问题
问题描述
最近刚学习前后端的知识,就简单的做了一个前后端分离的项目.当在vue中使用axios或者fetch等去获取spring的API接口的时候会报跨域错误即 CORS 跨域资源共享错误
简单地说 我的vue 运行在http://localhost:8080端口上 而spring 运行在http://localhost:8085端口上由于这两个端口不同所以在请求的时候视为跨域,这个时候就无法简单的通过请求获得。
解决方案
1.nginx
使用nginx代理,nginx反向代理原理如下
即我们客户端想要访问真正的后端的时候实际上是访问代理服务器,由代理服务器去转发到服务器去取回我们需要的数据。
由此,下载nginx在nginx.conf文件中输入自己要代理的数据。
server {
listen 8888;# 服务器监听的端口,前端访问这个端口
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /api/ {//监听的路径信息
proxy_pass http://<后端的IP或者域名>:<端口>;//监听到上述的路径后将转发到这个代理上去
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep- Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache- Control,Content- Type,Authorization,token';
}
}
让后启动nginx服务即可,此后把前端中应该访问地址 改为<后端的IP或地址>:<nginx监听的端口>我这里就是http://<ip或者域名>:8888。请求即可正常到达。
2.在后端中配置
因为后端使用spring,所以可以在controller层中添加一个annotation
@CrossOrigin(origins = "<这里填允许跨域访问的地址和端口信息>")
//比如@CrossOrigin(origins = "http://localhost:8080")
这个annotation可以在每个mapping中进行使用也可以对整个controller层进行使用。
preflight错误
在完成上述以后,get方法能够正常的使用而post方法不能正常使用,报了一个preflight错误,这个错误的原因是当我们的请求不是一个简单请求的使用,会先发一个询问信息,在发送post请求,如果我们直接发data过去服务器就会发生这个错误使用axios发送的默认是 application/json不是一个简单的请求,所以我们可以把他转为简单请求 Content-Type: application/x-www-form-urlencoded
如何解决
在vue项目中axios加上头信息 Content-Type: application/x-www-form-urlencoded然后使用qs.stringfy({这里是json格式的数据})把数据转化为如下信息,即可进行post,此时spring中
同时spring中相关的controller
@PostMapping(consumes = "application/x-www-form-urlencoded")
public void postToDb( Study study) throws Exception {
studyService.postToDb(study);
}
如上即可正常的post了