1、何为跨域
当浏览器发送XMLHttprequest请求时,根据浏览器的同源策略,当请求的地址与来源地址的域名、端口号任一值不相同时,均视为跨域请求。
跨域问题的原因:
- 跨域问题只存在浏览器上,由于浏览器的同源策略,会检查发送的请求的地址是否跨域。
- XMLHttprequest请求
- 跨域。
2、解决方案
前两种原因解决方案不太有效,
- 去除浏览器跨域限制。(具体方法需百度)
- 不使用XMLHttprequest请求,使用jsonp请求,有弊端只支持get请求,后端也需要修改代码。
主要采用解决跨域
两种方案:
- 被调用方 返回请求时,响应头添加字段,告诉浏览器允许跨域。
- 调用方:使用反向代理服务器,浏览器发送本地非跨域请求,反向代理服务器转发到实际跨域的被调用方,因为跨域问题只发生在浏览器上。(应用场景:当无法修改被调用方代码时),不多赘述,反向代理请自行百度。
被调用方解决方式
服务器端实现(tomcat、weblogic)(代码实现)
通用方式:添加filter如下
public class CrosFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
// origin为跨域的地址。
String origin = req.getHeader("Origin");
if (!org.springframework.util.StringUtils.isEmpty(origin)) {
//带cookie的时候,origin必须是全匹配,不能使用*
res.addHeader("Access-Control-Allow-Origin", origin);
}
String headers = req.getHeader("Access-Control-Request-Headers");
// 支持所有自定义头 因为自定义头,请求与返回必须一致。
if (!org.springframework.util.StringUtils.isEmpty(headers)) {
res.addHeader("Access-Control-Allow-Headers", headers);
}
//匹配所有方法
res.addHeader("Access-Control-Allow-Methods", "*");
//允许浏览器缓存预检 缓存时间为3600秒
res.addHeader("Access-Control-Max-Age", "3600");
//允许带cookie请求
res.addHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
spring框架跨域:使用注解:@CrossOrigin 可在Controller类上添加,也可使用在当个方法上。
nginx配置:
先在nign.conf配置文件中末尾添加
include意思是载入vhost文件夹下的所有.conf配置文件。
在nign.conf同文件夹下创建vhost文件,vhost里创建.conf配置如下
配置如下:
server_name指定ninx服务器域名为b.com。
//这句话意思是 当发送的请求为预检请求时,返回200.
if ($request_method = OPTIONS){
return 200;
}
以上就是所有的解决方案。
补充一点。
简单请求浏览器会先执行,后检查是否跨域;
非简单请求,浏览器会先发一个预检请求,检查是否跨域,跨域则不予许,否则执行请求。