代码这种东西就是得不断的使用,如果长时间不用就会生疏。今天偶然间,有人问我跨域的原理和怎么解决,说了一下,但是总是感觉还是差了点什么,特此温习一下。
跨域的产生
最根本的原因就是浏览器的同源策略,所谓"同源"指的是"三个相同" 协议相同、域名相同、端口相同,违反一个就会产生跨域问题。
请求的分类(简单请求和非简单请求)
- 请求方法是以下三种方法之一:HEAD,GET,POST;
- HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type(只限于三个值application/x-www-form-urlencoded、 multipart/form-data、text/plain)
凡是不同时满足上面两个条件,就属于非简单请求。
解决跨域问题的方式
- JSONP 方式
- 代理请求方式
- CORS 方式
1、JSONP 方式 (只能是 get )
-
实现原理
客户端网页通过添加一个
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute('type','text/javascript');
script.src = src;
document.body.appendChild(script);
}
window.onload = function (){
addScriptTag('http://example.com/ip?callback=foo');
}
function foo (data) {
console.log('response data:'+JSON.stringify(data));
}
请求时,接口地址是作为构架出的脚本标签的src的,这样,当脚本标签构建出来时,最终的src是接口返回的内容;
- 服务器端对应的接口在返回参数外面添加函数包裹层
foo({ 'test':'testData' });
2、CORS 方式
cors是一个W3C标准,全称是--跨域资源共享,其实所有的浏览器ajax请求都是基于CORS机制的,只是我们可能平时并不关心而已(所以说其实现在CORS解决方案主要是考虑后台该如何实现的问题 )。
3、方向代理
通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问。
ajax跨域的表现
- 第一种
No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 404
原因:本次请求时‘非简单请求’,所以请求会预先发送一个options请求;但是服务器端没有允许options请求,导致无法找到对应的接口地址
解决方案:服务器允许options请求 - 第二种
No 'Access-Control-Allow-Origin' header is present on the requested resource,并且The response had HTTP status code 405
原因:后台方法允许OPTIONS请求,但是一些配置文件中(如安全配置),阻止了OPTIONS请求,才会导致这个现象。
解决方案: 后端关闭对应的安全配置。 - 第三种
No 'Access-Control-Allow-Origin' header is present on the requested resource,并且status 200。
原因:服务器端后台允许OPTIONS请求,并且接口也允许OPTIONS请求,但是头部匹配时出现不匹配现象;
解决方案: 后端增加对应的头部支持 - 第四种
heade contains multiple values ','
原因:后台响应的http头部信息有两个Access-Control-Allow-Origin:,服务器端在项目的配置文件中配置了一次origin,然后在代码中有手动的添加了一次origin
解决方案:建议删除代码中手动添加的,只用项目配置中的即可