`
yiminghe
  • 浏览: 1431556 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

cross domain request

 
阅读更多

场景

跨域请求是随着应用服务化而越来越多遇到的问题,大体分为两类

 

1. 子域间通信:a.t.com 要和 b.t.com 通信

 

2. 完全不同域间通信:t.com 要和 m.com 通信

 

1 可以看做是 2 的特例,不过解决方法更简单点.

解决方案

完全不同域间通信

w3c 很早就考虑到了这种需求,提出了 Cross-Origin Resource Sharing 标准,通过定义一系列请求头和响应头,可以在客户端透明(或者经过很少的修改)得支持跨源的 xmlhttprequest。

 

服务器通过返回响应头进行权限控制,例如

 

Access-Control-Allow-Origin 控制那些外部请求可以访问该资源

 

Access-Control-Allow-Credentials 结合客户端 xmlhttprequest 的 withCredentials 属性可以控制是否发送 cookie 等验证信息

 

Access-Control-Allow-Headers 控制客户端可以发送的额外头部信息.

 

 

那么只要 b.t.com  的响应设置合适的头部信息,最好情况下 a.t.com 可以不经过任何修改就可以向 b.t.com 发请求.

ie 的例外

不出预料,ie 不完全支持此规范:

ie>=8

有自己的一套跨域请求机制 XDomainRequest ,通过替换 XmlHttpRequest 为 XDomainRequest 也可以往外部域发请求,但服务器端控制就少点,只能设置

 

Access-Control-Allow-Origin 控制那些外部请求可以访问该资源

 

也就意味着:不能发送 cookie 信息, 不能设置额外请求头。

ie<8 

则是完全不支持,流行的做法是 flash 模拟,安全则交给 crossdomain.xml 控制,目前看来, ie<8 且不装 flash 的确实很少,可行!凑巧的是 flash 在 ie 下携带 cookie 信息,在其他浏览器下则不携带 cookie 信息,如果一定要附带 cookie 信息,那 ie 全平台都要用 flash 方案了。

另一种思路:

jsonp 不多说,最简单的一种,虽然控制少点(但服务器通过 refer 仍然可以限制来源请求)以及不能 post 数据(写操作受限),也算一个不错的选择。

子域间请求

子域访问作为跨域访问的特例,上述方法的任意一种都可行,但由于请求双方间共享一个主域,因而存在另外一种方案:

 

cross sub domain xmlhttprequest using proxy page 

场景:

a.t.com 希望发请求给 b.t.com 的资源地址,但 b.t.com 的资源实际上只能通过 b.t.com 下的请求才能访问,而我们知道通过设置

 

document.domain = "t.com" ;

 

那么 a.t.com 就可以操作 b.t.com 的文档以及 window 对象。

 

具体做法为 引入 b.t.com/proxy.htm,内容为

 

<script>
    document.domain="t.com"
</script>

 

将其作为 iframe 嵌入到欲发请求的 a.t.com 页面,a.t.com 通过操纵 b.t.com/prxoy.html 自身的 xmlhttprequest 向 b.t.com 发请求,这样子就可以绕过 a.t.com 自己的 xmlhttprequest 同源限制了.

问题

domain 设置是不可逆的,一旦主页面设置了 domain,那么其包含的iframe除非设置和主页面相同的 domain,否则就不能再和主页面通信,会导致大量的已有代码修改。

 

推荐:一开始进行全局总体设计时就规定所有子域页面统统设置 domain 为主域(全局脚本统一设置?)。

All In One

通过统一的接口,实际上可以做出透明的请求发送客户端,调用者不需要考虑以上细节,只要指定请求地址,通过工厂模式系统自动生成合适的客户端进行处理.

 

 

 

  • 大小: 393.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics