一、跨域的出现
当前台调用后台接口是不是同一个域便出现ajax跨域。
8081的客户端访问 8080服务端接口时便出现No “Access-Control-Allow-Origin” header is present on the requested resource.
Origin is therefore not allowed access.
二、为什么会发生ajax跨域?
1、浏览器限制
后台正常返回,只是浏览器没有显示。
2、跨域
协议,域名,端口 有一处不一样就是跨域
3、XHR (XMLHttpRequest请求)
如果不是XHR 的请求,那么不会跨域,比如 img src="http://localhost:8080/get1" 这时不会报错
三、解决思路
1、浏览器
浏览器禁止检查
终端输入:C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security
2、XHR
JSONP,不是官方协定。“callback”是前后端约定好的
后端跟着修改,jsonp ①请求类型是script没有跨域问题,②服务器返回的是js脚本,③url 多了个callback
$.ajax({
url:base+"/get1",
dataType:"jsonp",
jsonp:"callback",//跟后端约定好的callback名字
cache:true, //请求可以被缓存
success:function(json){
retsult= json;
});
jsonp的弊端
1、后端需要同步修改来支持
2、只支持get请求
3、发送的不是xhr请求 (所以不能异步)
3、跨域
1、被调用方修改--支持跨域
服务端实现
先执行or先判断? 浏览器
Nginx实现
Apache实现
2、调用方修改--隐藏跨域
3-1、被调用解决 - filter解决方案
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;
String origin = req.getHeader("Origin");
if (!org.springframework.util.StringUtils.isEmpty(origin)) {
//带cookie的时候,origin必须是全匹配,不能使用*
res.addHeader("Access-Control-Allow-Origin", origin);
}
res.addHeader("Access-Control-Allow-Methods", "*");
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-Max-Age", "3600");
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
简单请求?非简单请求 OPTIONS预检命令
简单请求
方法为:
GET HEAD POST
请求header里面:
无自定义头
Content-Type 为以下几种
text/plain
multipart/form-data
application/x-www-form-urlencoded
工作中常见的【非简单请求】有
put,delete方法的ajax请求
发送json给事的ajax请求
带自定义头的ajax请求
询问服务器是否有指定的头
服务器增加对应请求头之后