Page 80 - JavaScript修炼之道
P. 80
70 第五部分 服务器端技术
任务 31 跨域“Ajax”(方法收集 1)
与第三方服务做数据交互的情况越来越多。在现在这个混搭流行的时代,我们的网页经常需
要与服务和内容提供者进行通信,在这个过程中,我们当然希望不要加重服务器的负担。
有不少跨域后台载入数据的办法。我会给出几个比较重要且可靠的方法,它们应该足够对付
你的实际需求了。
我先简要地说一下总体情况。
任何URL都能用所谓的服务器端代理 来载入数据。如果它对你有用的话,那就用它吧。
①
不过在处理文件上传、内容类型(content types)以及POST请求这类东西的时候,可能需
要做一些调整(不过一定要检查并过滤到来的请求,你不会希望自己的服务器莫名其妙地
为垃圾数据传输打开方便之门吧)。
②
未来进行这种操作的方式将是跨来源资源共享 (Cross-Origin Resource Sharing, CORS) 。
XHR2就是用的CORS ,这也是W3C指定的跨域数据请求的方式。然而,目前只有Firefox
③
3.5+、Safari 4+和Chrome支持它。尽管IE8实现了CORS的基本功能(只有GET,不支持自
定义头部,不支持证书等),不过它需要你使用一个名为 XDomainRequest 的自定义对象。
如果上面两个办法都不可用,那么你就只能使用JSON-P,或者同时使用动态/隐藏表单和
④
<iframe>了。
目前,还没有特别好的办法能在不用服务器端代理的情况下,就把复杂数据POST到另外
的域名。尽管存在一些应对手段(参见下一个任务),但没有一个能够解决全部问题。
右页中是这个任务的代码,其中给出了基于CORS的方法(无需额外代码,只用到XMLHttp-
Request)、基于服务器端代理的方法以及两个基于表单的动态方法,其中的一个方法用到了<iframe>
(另一个方法会返回204响应码,使得浏览器不会尝试跳转,所以我们可以不用隐藏的<iframe>)。
我必须强调,只有当你不想依赖于某个外部服务 时,才有必要动用表单和<iframe>,否则
⑤
你就应该选择YQL(这在下一个任务中讨论)。
——————————
① 将要请求数据的URL发给自己的服务器端,由自己的服务器端获取这个URL的数据之后再返回(比如用PHP的
readfile($uri);)。*
② 意思是实现了CORS的新版浏览器本身就能做跨域的Ajax请求。*
③ 关于CORS和XHR2的更多信息,请访问https://developer.mozilla.org/en/HTTP_access_control。
④ 隐藏表单 + <iframe> 一般用于数据提交(还是得放在url的参数里>﹏<),如果要把返回的数据传给父页面会遇
到iframe的权限问题,因为iframe除了src属性可写之外也是不能跨域。当然也不排除有一种极端的手段:在前面
设置的iframe A里再嵌套一个和A的父页面同域名的iframe B,把得到的返回数据放在B的src属性的参数(?后面)
或者标签(#后面)中,这样就可以由B把这些数据传给A的父页面了。*
⑤ 指YQL服务。如果通过YQL跨域的话系统的正常运行就依赖于YQL的正常运行。*