1. JSONP方式
原理是通过script标签的跨域特性来绕过同源策略。
具体利用jQuery的ajax属性dataType jsonp jsonpCallback。
2. 前后端设置请求头方式
注:Access-Control-Allow-Headers必须设置具体值,*值无效。
2.1 前端设置
let value = "you will see me.";
let url = "http://127.0.0.1:5688/test";
// 直接打开新窗口不会有跨域问题,只支持GET请求
let newWindow = window.open(url + "?value=" + value, "_blank");
newWindow.onload = function (e) {
newWindow.document.title = "调用测试服务";
};
$.ajax({
url: url,
method: "GET",
dataType: "JSON",
data: {value: value},
crossDomain: true,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,OPTIONS",
"Access-Control-Allow-Headers": "Content-Type,X-Requested-With,Cookies,Cookie,X-Auth-Token,token,auth,Authorization",
"Access-Control-Request-Methods": "GET,POST,PUT,DELETE,OPTIONS",
"Access-Control-Allow-Credentials": true,
"Access-Control-Max-Age": 86400
},
beforeSend: function (xhr) {
// 同headers
// xhr.setRequestHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,Cookies,Cookie,X-Auth-Token,token,auth,Authorization");
},
success: function (result, response, status) {
console.info(result);
},
error: function (xhr, state, thrown) {
layer.alert("服务器出错啦!", {icon: 5});
}
});
2.2 后端设置
参考1:https://developer.aliyun.com/article/753657
首先对OPTION请求放入HTTP 200的响应内容。
对于Preflight request询问中的的Access-Control-Request-Headers予以通过。
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String orignalHeader = request.getHeader("Origin");
if (orignalHeader != null ) {
Matcher m = CORS_ALLOW_ORIGIN_REGEX.matcher(orignalHeader);
if (m.matches()) {
response.addHeader("Access-Control-Allow-Origin", orignalHeader);
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.addHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
}
}
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
参考2:
public class ProcessInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
httpServletResponse.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
httpServletResponse.setHeader("X-Powered-By","Jetty");
String method= httpServletRequest.getMethod();
if (method.equals("OPTIONS")) {
httpServletResponse.setStatus(200);
return false;
}
System.out.println(method);
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
2.3 若有中间代理,如nginx需要添加一些头信息如下,不一定全部都需要。
add_header Access-Control-Allow-Origin "https://04007.com'" always;
add_header Access-Control-Allow-Headers "Content-type,Origin,X-Auth-Token,X-JSON,Cookies,Cookie,Content-Length" always;
add_header Access-Control-Allow-Methods "GET,POST,OPTIONS" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Max-Age "86400" always;
3. 代理服务器方式
使用代理服务器做路由转发,如nginx代理。