前后端分离导致跨域问题处理
前言
前后端项目分离,项目部署的时候会产生跨域的问题,本文梳理了跨域产生的原因和如何处理跨域问题。
一、跨域是什么?
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080/7001) |
二、跨域浏览器报错
三、跨域解决方案
1. 自建项目如何解决跨域
1.1 servlet项目
a. 单个请求处理方案
针对某个servlet里面的doPost或者doGet方法,按照下面的代码,在业务逻辑前面添加。
/* 允许跨域的主机地址 */
response.setHeader("Access-Control-Allow-Origin", "*");
/* 允许跨域的请求方法GET, POST, HEAD 等 */
response.setHeader("Access-Control-Allow-Methods", "*");
/* 允许跨域的请求头 */
response.setHeader("Access-Control-Allow-Headers", "*");
b. 全部请求处理方案
针对整个项目的全部请求,按照如下操作
1) 定义过滤器接口Filter的实现类,实现类中修改respone的头信息,把 “Access-Control-Allow-Origin” 的域名修改问请求方的域名,如下:
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class CORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "<请求方域名如:http://www.sohu.com>");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
2) 在web.xml中配置此过滤器:
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>filter.CORSFilter</filter-class>
</filter>
1.2 springboot项目
1.2.1 创建一个filter解决跨域。
@Component
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
1.2.2 使用@CrossOrigin这个注解在controller类中使用
@CrossOrigin(origins = "http://192.168.1.10:8080", maxAge = 3600)
@RequestMapping("rest_index")
@RestController
public class IndexController{
2. 公司项目如何解决跨域
2.1 uap项目
2.1.1 在main.js中,配置数据所在服务器的前缀(即固定部分),代码如下:
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api' //关键代码
关键代码:axios.defaults.baseURL = ‘/api’,作用是我们每次发送的请求都会带一个/api的前缀。
2.1.2 在config文件夹下的index.js文件中的proxyTable字段中,作如下处理:
dev: {
env: require('./dev.env'),
port: 8090,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target:'http://api.douban.com/v2', // 你请求的第三方接口
changeOrigin:true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
pathRewrite:{ // 路径重写,
'^/api': '' // 替换target中的请求地址,也就是说以后你在请求http://api.douban.com/v2/XXXXX这个地址的时候直接写成/api即可。
}
}
},
cssSourceMap: false
}
2.1.3 在具体使用axios的地方,修改url如下即可:
axios.get("/movie/top250").then((res) => {
res = res.data
if (res.errno === ERR_OK) {
this.themeList=res.data;
}
}).catch((error) => {
console.warn(error)
})
2.2 基建项目
基建项目采用公司v7平台,底层是 servlet架构,采用上面servlet的解决方案。
2.3 云监理项目
云监理项目属于互联网项目,通过nginx转发的方式实现。
location /hussarApi/ {
proxy_pass http://yjl.taimohongcheng.com:9999;
}
location /wx/ {
proxy_pass http://yjl.taimohongcheng.com:9001;
}
2.4 轻骑兵v8
refer-whitelist: # 使用前后分离,需要配置前端请求的白名单,防止跨域请求后台,例如前台请求地址为:http://192.168.6.14:8081/ 此处就配置为http://192.168.6.14:8081/
- http://localhost:8082/
- http://localhost:8081/
- http://localhost:8088/
- http://localhost:8089/
- http://loaclhost:8082/
- http://localhost:8080/
- http://zwyjl.taimohongcheng.com:8080/
总结
以上就是今天要讲的内容,本文仅仅简单介绍了几种比较通用的解决跨域的方法。希望通过本次内容的讲解,能让大家今后对此类问题有一个更加清晰的认识和解决方案。
参考资料
https://blog.csdn.net/wh_xmy/article/details/87705840
https://www.cnblogs.com/diandianquanquan/p/10607102.html
https://blog.csdn.net/wangxin1982314/article/details/50249543
https://www.cnblogs.com/zgrey/p/13972270.html