资讯专栏INFORMATION COLUMN

AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比

QiuyueZhong / 2583人阅读

摘要:补充同源策略还应该对一些特殊情况做处理,比如限制协议下脚本的访问权限。注意,该请求的查询字符串有一个参数,用来指定回调函数的名字,这对于是必需的。

1 前言:

首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源。
本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源---同源策略;其次,介绍JSONP这种仅能支持GET请求的跨域方式和CORS作对比;最后,阐述CORS的XHR解决方式和IE中的XDR解决方式,在此基础上提供了工具函数进行跨浏览器的HTTP请求对象创建。

2 跨域问题的源头---同源策略

在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它的目的是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?

很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。

那么什么叫相同域(同源),什么叫不同的域(不同源)呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.example.org),那么我们就可以认为它们是相同的域。比如 http://www.example.org/index....(默认端口号80可以省略)和http://www.example.org/sub/in...是同域,而http://www.example.org, https://www.example.org, http://www.example.org:8080, http://sub.example.org中的任何两个都将构成跨域。
注意:只有协议、域名、端口号完全一样才是同一域,其他情况,即使是相对应的IP和域名也是不同域,具体情况如下图:

(这个图片忘了从哪里引得了,感谢作者)

目前,如果非同源,共有三种行为受到限制。

(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。

作为前端开发者,我们很多时候要做的是突破这种限制。

补充:同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

3 跨域方式JSONP[参考1]

JSONP是JSON with Padding的简写,是应用JSON实现服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

它的基本思想是,网页通过添加一个

阅读需要支付1元查看
<