问题
因为最近在学习vue和springboot.用到了前后端分离.前端webpack打包运行的时候会启动nodejs的服务器占用8080端口,后端springboot自带tomcat启动占用1111端口(我自己设置的)...导致前端请求的ajax到后台会产生跨域问题...然后自己试了试发现有2种办法都可以解决.
利用SpringMVC @CrossOrigin注解
1 package com.labofjet.system.controller; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 6 //@CrossOrigin(value = "*", allowCredentials = "true") 7 public class BaseController { 8 protected Logger log = LoggerFactory.getLogger(this.getClass()); 9 }
CrossOrigin这个注解可以允许ajax跨域请求....但是有个很明显的缺点就是ajax会请求2次,第一次请求类型是options.查看是不是允许发起跨域请求.然后才会发起get呀post呀这样的请求...这就很蛋疼了.相当于需要花费额外的时间再请求上.毕竟请求次数翻倍了.
另外如果要传输cookies的话似乎需要额外设置
allowCredentials = "true"
具体我也没试过.因为那个时候我用另外一种方法去解决了,不过看api文档上是说设置成true就可以解决了..
这种方式除了请求次数变多以外,我感觉还有1个主要问题就是你得设置你允许哪些站点跨域访问你..你为了开发方便设置成*...那么实际上了生产..别人哪个域名都可以给你发跨域请求..这就很尴尬了..而且注解是写在代码里的.你很难在生产和开发中分别设置不同的值.
使用nginx作为反向代理
所以就有了这种方法...我觉得这是一种比较好的解决办法..为什么呢?
因为使用nginx作为反向代理的时候前端用户浏览器访问的是nginx的地址,是一个地址,ajax请求的地址也是这个地址,只是在nginx里配置了去找后台的api.所以没有跨域的问题的.
具体做法:
首先设置nginx代理所有请求
server { listen 1112; server_name 127.0.0.1; location / { proxy_pass http://127.0.0.1:8080/; } }
比如监听1112端口,所有请求都转发到8080的前端nodejs端口.
然后再配置后台数据的接口,比如/api/开头的请求都转发给springboot后台1111端口.
location /api/ { proxy_pass http://127.0.0.1:1111/; #index index.html index.htm; }
那么这样做的话需要前端代码里所有的ajax请求都加上api开头前缀...所以需要统一配置下...
1 const ajaxUrl = env === 'development' 2 ? '/api' 3 : env === 'production' 4 ? 'https://www.url.com' 5 : 'https://debug.url.com'; 6 7 util.ajax = axios.create({ 8 baseURL: ajaxUrl, 9 timeout: 30000 10 });
我前端ajax用的是axios...可以配置baseURL去控制请求的地址的前缀.所以还是蛮方便的.
这样就完成了.在用户浏览器看上去前后台数据都是从1112端口发来的,并不知道nginx做了反向代理.所有cookies也都写在1112端口下.所以没有跨域问题也没有cookies的问题.
小结
通过nginx或者其他反向代理工具把请求转发给前台和后台服务器可以比较方便的解决前后端分离跨域问题.