8种超详细Web跨域解决⽅案
⼀、什么是跨域
当a.qq域名下的页⾯或脚本试图去请求b.qq域名下的资源时,就是典型的跨域⾏为。跨域的定义从受限范围可以分为两种,⼴义跨域和狭义跨域。
(⼀)⼴义跨域
⼴义跨域通常包含以下三种⾏为:
1. 资源跳转:a链接、重定向。
2. 资源嵌⼊:<link>、<script>、<img>、<frame>等dom标签,还有样式中background:url()、@font-face()等⽂件外链。
3. 脚本请求:浏览器存储数据读取、dom和js对象的跨域操作、js发起的ajax请求等。
其中,资源跳转和资源嵌⼊⾏为可以正常请求到跨域资源,脚本请求在未经任何处理的情况下,通常会有跨域问题。
(⼆)同源策略
同源策略(Same origin policy, SOP)是⼀种约定,由Netscape公司1995年引⼊浏览器,它是浏览器最核⼼也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源策略是指“协议+域名+端⼝”三者相同。web后端是指什么
(三)狭义跨域
狭义跨域正是浏览器同源策略限制的⼀类请求场景,即我们通常说的跨域⾏为,通常包含以下三种⾏为:
1. cookie、localStorage和indexDB⽆法读取。
2. dom和js对象⽆法获取和操作。
3. ajax请求⽆法发送。
⼆、常见跨域场景
三、跨域解决⽅案
(⼀)ajax跨域请求解决⽅案
⽇常开发过程中,绝⼤多数前端页⾯都会向后端发送ajax请求进⾏数据交互。那么,ajax请求遇到跨域问题,如何进⾏解决呢。本⽂总结以下四种常见解决⽅案:
jsonp跨域
jsonp (JSON with Padding),是JSON的⼀种“使⽤模式”,可以让⽹页跨域读取数据。其本质是利⽤script标签的开放策略,浏览器传递callback参数到后端,后端返回数据时会将callback参数作为函数名来包裹数据,从⽽浏览器就可以跨域请求数据并定制函数来⾃动处理返回数据。
jsonp跨解实现流程:
jsonp跨域代码⽰例:
var script = ateElement('script');
/
/ 传参callback给后端,后端返回时执⾏这个在前端定义的回调函数
script.src = 'a.qq/index.php?callback=handleCallback';
document.head.appendChild(script);
// 回调执⾏函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
jsonp跨域优点:
jsonp兼容性强,适⽤于所有浏览器,尤其是IE10及以下浏览器。
jsonp跨域缺点:
没有关于调⽤错误的处理。
只⽀持GET请求,不⽀持POST请求以及⼤数据量的请求,⽽且也⽆法拿到相关的返回头,状态码等数据。
callback参数恶意注⼊,可能会造成xss漏洞。
⽆法设置资源访问授权。
跨域资源共享(CORS)
跨域资源共享(Cross-origin resource sharing,CORS)是⼀个 W3C标准,允许浏览器向跨域服务器发送请求,从⽽克服了ajax只能同源使⽤的限制。CORS需要浏览器和服务器同时⽀持。⽬前,所有主流浏览器(IE10及以上)使⽤XMLHttpRequest对象都可⽀持该功能,IE8和IE9需要使⽤XDomainRequest对象进⾏兼容。
CORS整个通信过程都是浏览器⾃动完成,浏览器⼀旦发现ajax请求跨源,就会⾃动在头信息中增加Origin字段,⽤来说明本次请求来⾃哪个源(协议+域名+端⼝)。因此,实现CORS通信的关键是服务器,需要服务器配置Access-Control-Allow-Origin头信息。当CORS请求需要携带cookie时,需要服务端配置Access-Control-Allow-Credentials头信息,前端也需要设置withCredentials。
浏览器将CORS请求分成两类:简单请求和⾮简单请求。简单请求需要满⾜以下两⼤条件:
1. 请求⽅法是以下三种⽅法之⼀:HEAD、GET、POST。
2. HTTP的头信息不超出以下⼏种字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限
于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain。
CORS简单请求跨域实现流程:
CORS简单请求跨域代码⽰例:
// IE8/9需⽤XDomainRequest兼容
var xhr = new XMLHttpRequest();
// 前端设置是否带cookie
xhr.withCredentials = true;
xhr.open('post', 'a.qq/index.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=saramliu');
if (adyState == 4 && xhr.status == 200) {
sponseText);
}
};
CORS跨域优点:
⽀持所有类型的HTTP请求,功能完善。
通过onerror事件监听进⾏调⽤错误处理;
通过Access-Control-Allow-Origin进⾏资源访问授权。
CORS跨域缺点:
⽬前主流浏览器(IE10及以上)都⽀持CORS,但IE8和IE9需要使⽤XDomainRequest对象进⾏兼容,IE7及以下浏览器不⽀持。
Flash跨域(仅供IE7及以下浏览器参考使⽤)
由于IE7及以下浏览器默认是不兼容跨域请求的,那么在不改造后端的情况下,可以考虑使⽤Flash进⾏跨域请求。
Flash在进⾏跨域请求时,默认⾸先会发送预检请求,检查服务器域名根⽬录下的l⽂
件,判断请求域是否合法。如果域名不合法,Flash直接封杀请求;如果域名合法,则发送真实请求,获取数据并返回给前端页⾯。
(1)cross-domain-policy
site-control
allow-access-from
allow-access-from-identity
allow-http-request-headers-from
(2)site-control
是否允许加载其他策略⽂件,属性值permitted-cross-domain-policies允许的值有:
none,不允许加载策略⽂件(包括该主策略⽂件)。
master-only,仅允许加载主策略⽂件。
by-content-type,仅允许加载 HTTP/HTTPS 协议下Content-Type为text/x-cross-domain-policy的策略⽂件。
by-ftp-filename,仅允许加载FTP协议下⽂件名为l的策略⽂件。
all,允许加载任何策略⽂件。
(3)allow-access-from
⽤于授权数据访问的请求域,具有以下属性:
domain,指定授予权限的域,可以是域名或IP地址。
to-ports,指定授予权限的socket连接端⼝范围,以逗号分隔的端⼝列表,端⼝范围通过在两个端⼝号之间插⼊短划线-指定。
secure,指定信息是否经加密传输。
(4)allow-access-from-identity
允许有特定证书的请求域跨域访问⽬标域上的资源。
(5)allow-http-request-headers-from
⽤于授权发送⽤户定义HTTP头的请求域,具有以下属性:
domain,指定授予权限的域,可以是域名或IP地址。
headers,表明允许发送的HTTP头,以逗号分隔。
secure:指明信息是否经加密传输。l⽂件配置⽰例:
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*.qq"/>
<allow-http-request-headers-from domain="*" headers="*"/> </cross-domain-policy>
Flash跨域实现流程:
Flash跨域代码⽰例:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。