最近自己写了一个js组件,该js组件是提供给第三方使用的,而js组件中涉及了ajax请求,于是乎就出现了跨域请求问题。下面记录一下自己的解决路程。
参考:跨域请求详解
个人理解:我理解的跨域就是,两个不同的ip或者域名,进行访问和数据交换,此时如果不做处理,便会发生跨域请求问题。详细解释看上面链接。
我自己就是因为js提供给其他服务器进行调用,而我的js里面设计到一个ajax请求,所以在第三方服务器调用我的js进行操作的时候,就设计到了两个服务器之间的数据交互问题,即跨域问题。
了解了什么是跨域,那么怎么定位自己的错误是跨域导致的呢?我一般是根据报错来定位。调用js时,我的报错如下:
如果你也出现报错这个,恭喜你,你确实跨域无疑了。那么如何解决这个问题呢,网上各种答案都有,我这里总结一下。便于以后自己的出现同样问题的时候,能够及时找到最优的答案。
目前我了解的解决跨域的几种方式:手写过滤器
,手写拦截器
,jsonnp
,注解方式
,配置nginx反向代理
,共五种解决方式。
通过过滤器开放需要访问的接口(我用的这种,推荐)
(1)写一个过滤器:
package com.ninesword.utils;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class CrossFilter implements Filter {
private static Logger logger = LoggerFactory.getLogger(CrossFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
logger.debug("跨域请求进来了。。。");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
httpServletRequest.getSession();
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "*");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Content-type", "application/json");
httpResponse.setHeader("Cache-Control", "no-cache, must-revalidate");
chain.doFilter(request, httpResponse);
}
}
在web.xml中配置过滤器和需要过滤的接口
<filter>
<filter-name>corsfilter-name>
<filter-class>com.ninesword.utils.CrossFilterfilter-class>
filter>
<filter-mapping>
<filter-name>corsfilter-name>
<url-pattern>/jsForSdp/*url-pattern>
filter-mapping>
经过以上配置,已经可以成功跨域了,亲测有效哦。
这个方法,是一个大佬推荐的,我没有试过。这里推荐文章:[java-拦截器实现跨域支持](https://blog.csdn.net/zpf0918/article/details/52624813)
网上各种针对jsonnp实现跨域的文章很多,但是这种,据说只对get请求有效,不推荐。我用的是原声js写的组件,jsonnp常见于jquery ajax中,所以,这里无法解决我的问题,还是说下它怎么实现的吧。
使用jsonnp还是很简单的,如果你用的是jquery的话就更好了。
$.ajax({
url: "你的url",
type: 'GET',
dataType: 'JSONP',//重点在这里,加上这个属性就可以跨域请求了
success: function (data) {
}
});
我的框架是ssh。这里有注解可以解决跨域问题,本人没有试过,但是确实简单有效。推荐链接:
springmvc @crossorigin跨域
利用nginx 反向代理解决跨域问题
这里个人推荐的还是第一种解决方式,经过验证确实有效。如果你有更好的方式或者见解,请留言。谢谢