我这里有个需求需要相同的域名访问不同服务器上部署的项目,用到了nginx反向代理,使用反向代理就会导致AJAX跨域请求问题。
ajax请求服务器数据,无法获取到当前session,手机UC、微信、支付宝内置浏览器则返回error信息
{"readyState":0,"responseText":"","status":0,"statusText":"error"}
网上有很多的解决方法,nginx添加header或者后端服务器添加header,我这里用的是过滤器方式。
//创建过滤器,为response添加header
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", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
经过测试,谷歌浏览器没问题,火狐和手机UC浏览器,微信内置浏览器,支付宝内置浏览器不行。
于是我又各种搜索ing……
最终找到一个解决方法。我用的是jquery的ajax请求,在ajax中添加xhrFields字段
$.ajax({
dataType : "json",
url : url,
type : "POST",
timeout : 60000,
//添加xhrFields
//将withCredentials设置为true,允许ajax跨域请求
xhrFields: {
withCredentials: true
},
cache: false,
data : dataParams,
success: function(data) {
},
error: function(xml, eType, e) {
}
});
经过测试,谷歌浏览器没问题,火狐浏览器也没有问题,但是手机UC浏览器,微信内置浏览器,支付宝内置浏览器还是不行。
进过我一顿研究实验,发现是手机内置浏览器验证跨域比较严格,不支持适配符的方式。
//是这个设置的原因,UC和微信、支付宝内置浏览器不支持适配符【*】
response.setHeader("Access-Control-Allow-Origin", "*");
//需要更明确的Origin地址,改成你的请求域名即可
response.setHeader("Access-Control-Allow-Origin", "https://www.example.com");
再次实验手机UC浏览器,微信内置浏览器,支付宝内置浏览器跨域请求成功。
网上的方法说明都很简单,不是很全面,还有很多人问PC端浏览器使用没问题,在手机端浏览器就不能请求的问题,我猜想应该是与我相同的问题,在此记录解决方法希望能够帮助到更多人。