几年前,网站开发者都因为ajax的同源策略而撞了南墙。当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访 问,对此我们哀叹不已。每个人在他们自己的网站上建立代理(which was the onset of a new host of open redirect problems)来摆脱这种限制。虽然开发者利用服务器代理和其它技巧避开了这种限制,而在社区的抗议者允许ajax在本地跨域调用。许多人还没意识到 当前几乎所有的浏览器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome)都可通过名为Cross-Origin Resource Sharing的协议支持ajax跨域调用。

跨域资源共享(CORS)

Cross-Origin Resource Sharing (CORS)是W3c工作草案,它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。

对一个简单的请求,没有自定义头部,要么使用GET,要么使用POST,它的主体是text/plain,请求用一个名叫Orgin的额外的头部发送。Origin头部包含请求页面的头部(协议,域名,端口),这样服务器可以很容易的决定它是否应该提供响应。

Origin: http://www.nczonline.net

如果服务器确定请求被通过,它将发送一个Access-Control-Allow-Origin头部响应发送请求的同一个源,如果是一个公共资源,则返回“*”。如:

Access-Control-Allow-Origin: http://www.nczonline.net

如果头部丢失,或者源不匹配,那么浏览器将拒绝请求。如果一切顺利,浏览器将处理请求。注意,请求和响应都不包括cookie信息。

先前提到的所有浏览器都支持这些简单的请求。FF3.5 +,Safari 4和chrome通过使用XMLHttpRequest对象支持其使用。当尝试在不同域打开一个资源时,不需任何代码,这个行为会自动触发。如:

var xhr = new XMLHttpRequest();

xhr.open("get", "http://www.nczonline.net/some_resource/", true);

xhr.onload = function(){  //instead of onreadystatechange

//do something

};

xhr.send(null);

在IE8中也是一样,用同样的方式你需要使用XDomainRequest object。

var xdr = new XDomainRequest();

xdr.open("get", "http://www.nczonline.net/some_resource/");

xdr.onload = function(){

//do something

};

xdr.send();

Mozilla小组在他们关于CORS的留言中建议应该检查withCredentials属性的存在性,从而决定浏览器是否通过XHR支持CORS。你可以合并XDomainRequest 对象的存在性来支持所有的浏览器:

function createCORSRequest(method, url){

var xhr = new XMLHttpRequest();

if ("withCredentials" in xhr){

xhr.open(method, url, true);

} else if (typeof XDomainRequest != "undefined"){

xhr = new XDomainRequest();

xhr.open(method, url);

} else {

xhr = null;

}

return xhr;

}

var request = createCORSRequest("get", "http://www.nczonline.net/");

if (request){

request.onload = function(){

//do something with request.responseText

};

request.send();

}

Firefox, Safari, 和Chrome的XMLHttpRequest对象与IE的XDomainRequest对象有着相似的充分的接口,这些模式运行的很好。常见的接口属性/方法:

· abort()——用来终止已在进程中请求。

· Onerror()——替代onreadystatechange方法来探测错误。

· Onload()——替代onreadystatechange方法来探测成功。

· responseText——用来取得响应地文本。

· send()——用来发送请求。

Preflighted请求

除了GET或POST,通过一种称之为preflighted请求的服务器透明验证机制,CORS允许使用自定义的头部和方法,以及不同主体内容类型。当你尝试使用高级选项中的一个来试着建立一个请求时,这时就建立了一个preflighted请求。该请求使用可选的方法,并发送如下头部:

· 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——preflighted 请求应该被缓存的时间。

如:

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

preflighted 请求一旦作出,结果将按响应中规定的时间缓存下来;第一次做出这样的请求,你将引发一次额外的HTTP请求。

Firefox 3.5+, Safari 4+和Chrome都支持preflighted 请求,IE8则不支持。

Credentialed请求

默认状态下,跨域请求不提供证书(cookie、HTTP身份验证、客户端SSL证书)。你可以规定一个请求应该通过设置withCredentials属性为true来发送证书。如果服务器允许credentialed请求,那么它将用下面的头部作出响应:

如果一个credentialed请求被发送,这个头部不会作为响应地一部分被发送。浏览器不会将响应传递给JavaScript(responseText是一个空字符串,状态为0,onerror()被调用)。注意,服务器也能发送这个HTTP头部作为preflight响应的一部分,以此来表明该源允许发送credentialed请求。

Access-Control-Allow-Credentials: true

IE8不支持withCredentials属性,Firefox 3.5+, Safari 4+和Chrome都支持它。

结论

在 现代web浏览器中对跨域AJAX调用有许多可靠地支持,然而,大多数开发者仍没意识这些强大的功能力。只需在JavaScript和服务器端做一点额外 的工作以保证正确的头部被发送即可使用它。在允许高级请求和credentialed请求方面,IE8的执行有些滞后,但希望它对CORS的支持将会继续 改进。如果你想了解更多,我强烈建议你检查Arun Ranganathan的示例页。

跨域资源共享(CORS)--跨域ajax相关推荐

  1. php跨域资源共享,CORS 跨域资源共享

    CORS (Cross-Origin Resource Sharing) 跨域资源共享 为什么需要 CORS 首先,跨域指的是同一个域名下的资源,同时要注意域名与子域名,比如 developers.e ...

  2. 跨域资源共享CORS详解

    最近深入了解了CORS的相关东西,觉得阮一峰老师的文章写得最详细易懂了,所有转载作为学习笔记. 原文地址:跨域资源共享 CORS 详解 CORS是W3C的一个标准,全称是跨域资源共享(Cross-or ...

  3. xmlhttprequest 跨域_跨域资源共享(CORS)安全性

    跨域资源共享(CORS)安全性 背景 提起浏览器的同源策略,大家都很熟悉.不同域的客户端脚本不能读写对方的资源.但是实践中有一些场景需要跨域的读写,所以出现了一些hack的方式来跨域.比如在同域内做一 ...

  4. php cros跨域处理,CORS跨域问题解决方案

    跨域问题主要是由于浏览器同源策略限制引起,简单来说,就是只相信自己人,不相信外人,只响应同域名发来的http请求,不相信其他域名发来的http请求.好处是减少上当受骗的几率,缺点是不符合webapi的 ...

  5. Spring 设置跨源资源共享(CORS)

    文章目录 跨源资源共享策略问题 1. Spring 解决方式:设置 CORS 2. CORS 的前世今生 2.1 CSRF 跨站请求伪造漏洞 2.2 浏览器同源策略的产生 同源的定义 2.3 跨源资源 ...

  6. AJAX跨域资源共享 CORS 详解

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  7. 跨域资源共享 CORS

    简介 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请 ...

  8. Access-Control-Allow- 设置跨域资源共享CORS详解

    跨域访问的项目常在过滤器或者拦截器中添加如下配置: response.setHeader("Access-Control-Allow-Origin", "*") ...

  9. 跨域资源共享 CORS 详解

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin re ...

  10. 安全系列之:跨域资源共享CORS

    文章目录 简介 CORS举例 CORS protocol HTTP request headers HTTP response headers 基本CORS Preflighted requests ...

最新文章

  1. 10任务栏全屏时老是弹出_Deepin 15.10 发布,深度操作系统
  2. CTFshow 爆破 web28
  3. 机器学习大牛是如何选择回归损失函数的?
  4. Vue v-for使用详解
  5. 智能自动PPR更改事件策略
  6. Python---实验八
  7. mysql安装完只有黑框_MySQLMySQL的安装及安装中存在的问题
  8. android canvas 清空画布,清除canvas画布内容(点擦除+线擦除)
  9. 《java入门第一季》之类面试题
  10. 设计mysql存储过程,MySQL的存储过程设计的例子
  11. AutoJs学习-TTS抢语音红包
  12. 明御:APT攻击预警平台
  13. IP欺骗攻击原理及如何修改IP
  14. 解决对话框的圆角背景图片黑色部分
  15. 网爆B站面试官在北邮校招时,炫耀身价过亿资产、贬低北邮应试者:你们太浮躁,眼界太窄
  16. DCI format 5A相关学习
  17. Ebox系列Corecon不同版本不宜安装在一起
  18. 大数据反欺诈+保险赔付:看互联网保险如何普惠
  19. jsp---JSTL核心标签
  20. 大智慧交易系统测试软件,均线交易系统测试

热门文章

  1. MVC框架详解--Servlet+JSP+JavaBean模式(MVC)开发复杂的web应用
  2. WCF 宿主与通信模式(二)
  3. JVM:如何分析线程堆栈
  4. 浅述WinForm多线程编程与Control.Invoke的应用
  5. 编译器错误 CS1026
  6. 不同长度数据项的排序
  7. SQLServer中批量插入数据方式的性能对比 (转)
  8. mysql最大连接数512_MySQL服务器最大连接数怎么设置才合理
  9. 通过远程(vnc)无法打开qtcreator
  10. linux命令添加文件权限,linux 的常用命令及文件权限管理