JavaScript跨域方法总结

同源安全策略

默认情况下,XHR 对象只能访问与包含它的页面位于同一个域中的资源。这种安全策略可以预防某些恶意行为。但是,实现合理的跨域请求对开发某些浏览器应用程序也是至关重要的。

一、CORS

Cross-Origin Resource Sharing,跨域资源共享

1、原理

CORS是 W3C 的一个工作草案,定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通。CORS 背后的基本思想,就是使用自定义的 HTTP 头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
比如一个简单的使用 GET 或 POST 发送的请求,它没有自定义的头部,而主体内容是 text/plain。在发送该请求时,需要给它附加一个额外的Origin 头部,其中包含请求页面的源信息(协议、域名和端口) ,以便服务器根据这个头部信息来决定是否给予响应。下面是 Origin 头部的一个示例:
Origin: http://www.nczonline.net
如果服务器认为这个请求可以接受,就在 Access-Control-Allow-Origin 头部中回发相同的源信息(如果是公共资源,可以回发 “*” )。例如:
Access-Control-Allow-Origin:http://www.nczonline.net
如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就会驳回请求。正常情况下,浏览器会处理请求。注意,请求和响应都不包含 cookie 信息。

2、IE对CORS的实现

微软在 IE8 中引入了 XDR( XDomainRequest )类型。这个对象与 XHR 类似,但能实现安全可靠的跨域通信。XDR 对象的安全机制部分实现了 W3C 的 CORS 规范。以下是 XDR 与 XHR 的一些不同之处。
 cookie 不会随请求发送,也不会随响应返回。
 只能设置请求头部信息中的 Content-Type 字段。
 不能访问响应头部信息。
 只支持 GET 和 POST 请求。
这些变化使 CSRF(Cross-Site Request Forgery,跨站点请求伪造)和 XSS(Cross-Site Scripting,跨站点脚本)的问题得到了缓解。被请求的资源可以根据它认为合适的任意数据(用户代理、来源页面等)来决定是否设置 Access-Control- Allow-Origin 头部。作为请求的一部分, Origin 头部的值表示请求的来源域,以便远程资源明确地识别 XDR 请求。
XDR对象的使用方法与 XHR对象非常相似。 也是创建一个 XDomainRequest 的实例, 调用 open()方法,再调用 send() 方法。但与 XHR 对象的 open() 方法不同,XDR 对象的 open() 方法只接收两个参数:请求的类型和 URL。
所有 XDR 请求都是异步执行的,不能用它来创建同步请求。

3、其他浏览器对CORS的实现

通过 XMLHttpRequest对象实现了对 CORS 的原生支持。在尝试打开不同来源的资源时,无需额外编写代码就可以触发这个行为。 要请求位于另一个域中的资源, 使用标准的 XHR对象并在 open() 方法中传入绝对 URL即可。

xhr.open("get", "http://www.somewhere-else.com/page/", true);

与 IE 中的 XDR 对象不同,通过跨域 XHR 对象可以访问 status 和 statusText 属性,而且还支持同步请求。跨域 XHR 对象也有一些限制,但为了安全这些限制是必需的。以下就是这些限制。
 不能使用 setRequestHeader() 设置自定义头部。
 不能发送和接收 cookie。
 调用 getAllResponseHeaders() 方法总会返回空字符串。
由于无论同源请求还是跨源请求都使用相同的接口,因此对于本地资源,最好使用相对 URL,在访问远程资源时再使用绝对 URL。这样做能消除歧义,避免出现限制访问头部或本地 cookie 信息等问题。

4、Preflighted Reqeusts

CORS 通过一种叫做 Preflighted Requests 的透明服务器验证机制支持开发人员使用自定义的头部、GET 或 POST之外的方法,以及不同类型的主体内容。在使用下列高级选项来发送请求时,就会向服务器发送一个 Preflight 请求。这种请求使用 OPTIONS 方法,发送下列头部。
 Origin :与简单的请求相同。
 Access-Control-Request-Method :请求自身使用的方法。
 Access-Control-Request-Headers :(可选)自定义的头部信息,多个头部以逗号分隔。
以下是一个带有自定义头部 NCZ 的使用 POST 方法发送的请求。

Origin: http://www.nczonline.net
Access-Control-Request-Method: POST
Access-Control-Request-Headers: NCZ

发送这个请求后,服务器可以决定是否允许这种类型的请求。服务器通过在响应中发送如下头部与浏览器进行沟通。
 Access-Control-Allow-Origin :与简单的请求相同。
 Access-Control-Allow-Methods :允许的方法,多个方法以逗号分隔。
 Access-Control-Allow-Headers :允许的头部,多个头部以逗号分隔。
 Access-Control-Max-Age :应该将这个 Preflight 请求缓存多长时间(以秒表示)。
例如:

Access-Control-Allow-Origin: http://www.nczonline.net
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: NCZ
Access-Control-Max-Age: 1728000

Preflight 请求结束后,结果将按照响应中指定的时间缓存起来。而为此付出的代价只是第一次发送这种请求时会多一次 HTTP 请求。

5、带凭据的请求

默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端 SSL 证明等) 。通过将withCredentials 属性设置为 true ,可以指定某个请求应该发送凭据。如果服务器接受带凭据的请求,会用下面的 HTTP 头部来响应。

Access-Control-Allow-Credentials: true</
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值