Cors解决ajax跨域

时间:2022-12-05 13:59:13
  • Cors简介
  • Cors使用示例
  • Cors对比jsonp

Cors简介

当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求(下图来源网络)

Cors解决ajax跨域
出于安全性考虑,浏览器会限制或拦截跨域的请求,这样的场景非常多,同时也衍生了许多解决跨域的方法。例如下错误就是跨域问题引起
Cors解决ajax跨域
本节讲述从服务端入手,利用cors(跨域资源共享)技术来解决ajax跨域问题。cors(跨域资源共享)是通过目标服务器返回的Header设置来控制是否可跨域。其中重要的一个参数即 Access-Control-Allow-Origin(访问控制允许来源),通过这个参数指定可以接收的请求资源。从实现上来说,用拦截器或过滤器等等。

使用示例

ajax请求中添加
withCredentials: true
web.xml中添加
<!-- 解决Ajax POST请求接口跨域问题 -->
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.simonsfan.activity.filter.CorsFilter</filter-class>
<init-param>
<param-name>allowOrigin</param-name>
<param-value>http://vip.aiquwang.com</param-value>;
</init-param>
<init-param>
<param-name>allowMethods</param-name>
<param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
</init-param>
<init-param>
<param-name>allowCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>allowHeaders</param-name>
<param-value>Content-Type</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这个在xml中定义了一些常量,也可以直接定义在下面的CorsFilter中;

allowOrigin:允许来源(协议+域名+端口);

allowMethods:Http请求方法(get/post/put/delete/options);

allowCredentials:是否允许发送cookie及Http认证信息到服务端(true/false);

allowHeaders:目标服务器支持的头信息字段(Content-Type);

自定义过滤器CorsFilter
public class CorsFilter implements Filter {
private String allowOrigin;
private String allowMethods;
private String allowCredentials;
private String allowHeaders;
private String exposeHeaders;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
allowOrigin = filterConfig.getInitParameter("allowOrigin");
allowMethods = filterConfig.getInitParameter("allowMethods");
allowCredentials = filterConfig.getInitParameter("allowCredentials");
allowHeaders = filterConfig.getInitParameter("allowHeaders");
exposeHeaders = filterConfig.getInitParameter("exposeHeaders");
}

@Override
public void destroy() {
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!StringUtils.isEmpty(allowOrigin)) {
List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));
if (!CollectionUtils.isEmpty(allowOriginList)) {
String currentOrigin = request.getHeader("Origin");
if (allowOriginList.contains(currentOrigin)) {
response.setHeader("Access-Control-Allow-Origin", currentOrigin);
}
}
}
if (!StringUtils.isEmpty(allowMethods)) {
response.setHeader("Access-Control-Allow-Methods", allowMethods);
}
if (!StringUtils.isEmpty(allowCredentials)) {
response.setHeader("Access-Control-Allow-Credentials", allowCredentials);//是否允许发送cookie和http认证信息到服务器
}
if (!StringUtils.isEmpty(allowHeaders)) {
response.setHeader("Access-Control-Allow-Headers", allowHeaders);
}
if (!StringUtils.isEmpty(exposeHeaders)) {
response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
}
chain.doFilter(request, response);
}
}

Cors对比jsonp

Cors可以实现和jsonp同样的效果,但是比jsonp强大些,它支持所有类型的http请求,而jsonp只支持get方式的请求。上述代码顺利解决ajax跨域问题