首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

利用CORS兑现跨域请求

2012-08-26 
利用CORS实现跨域请求跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一

利用CORS实现跨域请求

跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题。不过现在,我们可以考虑一下W3C中一项新的特性——CORS(Cross-Origin Resource Sharing)了。

?

本文的所有代码均来自http://www.html5rocks.com/en/tutorials/cors/,如果您对其中的任何技术细节存在疑问,请以原文为准。

客户端

创建XmlHttpRequest对象

对于CORS,Chrome、FireFox以及Safari,需要使用XmlHttpRequest2对象;而对于IE,则需要使用XDomainRequest;Opera目前还不支持这一特性,但很快就会支持。

因此,在对象的创建上,我们不得不首先针对不同的浏览器而进行一下预处理:

?

事件处理

原先的XmlHttpRequest对象仅仅只有一个事件——onreadystatechange,用以通知所有的事件,而现在,我们除了这个事件之外又多了很多新的。

事件说明onloadstart*当请求发生时触发onprogress读取及发送数据时触发onabort*当请求被中止时触发,如使用abort()方法onerror当请求失败时触发onload当请求成功时触发ontimeout当调用者设定的超时时间已过而仍未成功时触发onloadend*请求结束时触发(无论成功与否)

注:带星号的表示IE的XDomainRequest仍不支持。
数据来自http://www.w3.org/TR/XMLHttpRequest2/#events。

绝大多数情况下,我们只需要和onloadonerror打交道,就像下面这样:

?

服务端

一个CORS请求可能包含多个HTTP头,甚至有多个请求实际发送,这对于客户端的开发者来说通常是透明的。因为浏览器已经负责实现了CORS最关键的部分;但是服务端的后台脚本则需要我们自己进行处理,因此我们还需要了解到服务端到底从浏览器那里收到了怎样的内容。

先来看看流程图吧。

利用CORS兑现跨域请求

CORS分类

CORS可以分成两种:

  • 简单请求
  • 复杂请求

    一个简单的请求大致如下:

    • HTTP方法是下列之一
      • HEAD
      • GET
      • POST
      • HTTP头包含
        • Accept
        • Accept-Language
        • Content-Language
        • Last-Event-ID
        • Content-Type,但仅能是下列之一
          • application/x-www-form-urlencoded
          • multipart/form-data
          • text/plain

            任何一个不满足上述要求的请求,即被认为是复杂请求。一个复杂请求不仅有包含通信内容的请求,同时也包含预请求(preflight request)。

            简单请求

            为了搞清楚复杂请求与简单请求有何区别,我们首先来看看简单请求是怎样处理的。

            JavaScript:

            XMLHttpRequest cannot load http://api.alice.com. Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
            ?不过很可惜,浏览器并不会给出详细的错误情况,仅仅是告知我们出错而已。

            安全问题

            跨域请求始终是网页安全中一个比较头疼的问题,CORS提供了一种跨域请求方案,但没有为安全访问提供足够的保障机制,如果你需要信息的绝对安全,不要依赖CORS当中的权限制度,应当使用更多其它的措施来保障,比如OAuth2。

            已知问题

            CORS是W3C中一项较“新”的方案,以至于各大网页解析引擎还没有对其进行完美的实现。下面是截至2011年11月13日时的已知问题:

            • getAllResponseHeaders()方法无法获取Access-Control-Expose-Headers当中要求的信息。在Chrome/Safari当中,仅仅只有简单的头部能够读取,其他无法获取;在FireFox当中,无法获得任何信息。(FireFox Bugzilla/Webkit Bugzilla)
            • 在Safari当中,使用GETPOST方法的复杂请求发送时没有发送预请求的环节。
            • onerror触发时statusText获取不到任何内容。
            • Opera截至11.60仍旧不支持CORS,但在12当中会支持(Opera Core Concerns – CORS goes mainline)。

              阅读更多
              • CORS的W3C规范
              • 为CORS而配置服务器

                [转自:http://newhtml.net/using-cors/]

热点排行