跨域请求详解

同源策略

Ajax的一个限制是同源策略(same origin policy),它要求所有请求必须来自同一个域名、子域名,并且地址的端口也应当一致。主要原因是处于安全考虑:因为当一个ajax请示被发送,所有的请求都会附带主域的cookie信息一起发送。也就是说,对于远程服务来讲,请求如果是来自于登陆后的用户,若没有同源策略的限制,攻击者就有可能获取你的Gmail里的邮件、得到你的 Fackbook 状态或者你 Twitter 中的好友,这是一个非常严重的安全性问题。

但是,尽管出于安全问题的考虑而提出了同源策略,这也对那些的确需要跨域获取合法数据的开发者造成了一些不方便。诸如Adobe Flash和JAVA之类的技术已经着手解决了这个问题,通常是使用跨域策略文件。现在针对Ajax,也提出了CORS(cross-origin resource sharing)的标准规范。

CORS

CORS打破同源策略的限制,赋予了前端代码访问可信的远程服务的权限。主流的浏览器都很好的支持这个规范,除非使用IE6,基本上可以很好地使用它。

支持CORS的浏览器:

  • IE>=8(需要安全caveat)
  • Firefox>=3
  • Safari:完全支持
  • Chrome:完全支持
  • Opera:不支持

CORS的使用非常简单。如果想将你的服务器添加为受信任的数据源,只需在HTTP协议的响应头里加几行:

Access-Control-Allow-Origin:example.com

Access-Control-Request-Method:GET,POST

这两个头字段会对来自example.com的跨域GET和POST请求做验证。多个值之间用逗号分隔,就像上面提到的GET,POST值一样。如果要添加多个域名,将域名列在 Access-Control-Allow-Origin头字段之中,每两个域名之间用逗号分隔。如果允许来自任意域的访问请求,则需要在源中加入通配符(*)。

对于有些浏览器,比如Safari,它会首先发起一个OPTIONS请求以检查服务器是否允许跨域的请求。

另一方面,Firefox则会直接发起跨域请求,但当服务器没有配置CORS头字段时会抛出一个安全异常。需要注意一下这种浏览器行为的不同。

你甚至可以使用 Access-Control-Allow-Headers头字段来认证自定义的请求头:

Access-Control-Request-Headers:Authorization

这也意味着客户端可以在Ajax请求中添加自定义头,比如使用开放认证(OAuth)对请求进行签名:

var req=new XMLHttpRequest();

req.open("POST","/endpoint",true);

req.setRequestHeader("Authorization",oauth_signature);

XDomainRequest

不幸的是,尽管CORS是可以正常工作在IE8及更高版本的IE中的,微软还是选择另辟蹊径,不兼容规范且对W3C工作组制定的标准视而不见。微软使用了一个自己的对象XDomainRequest,用来代替XMLHttpRequest进行跨域通信。它的接口和XMLHttpRequest的非常像,它包含一系列约束和限制,比如只支持GET和POST方法,不支持验证和自定义字段,并且支持“Content-Type:text/plain"类型的请求。

如果你满足来这些限制条件,就可以在IE8中使用正确的Access-Control头字段和XDomainRequest来实现CORS,网页可以直接在浏览器中生成跨域数据请求,而不必使用服务器到服务器的请求。跨域请求需要经过网页和服务器的相互同意。通过利用window对象创建XDomainRequest对象,并打开到特定域的连接,可以在网页中启动一个跨域请求。浏览器将通过发送带有源值的Origin请求头,从特定域的服务器中请求数据。如果服务器响应的Access-Control-Allow-Origin响应头为*或请求页面的确切URL,则浏览器将完成连接,然后可以使用XDomainRequest跨域请求目标服务器上的数据。XDomainRequest使用如下所示:

// 1. Create XDR object:
var xdr = new XDomainRequest(); 

// 2. Open connection with server using GET method:
xdr.open("get", "http://www.contoso.com/xdr.aspx");

// 3. Send string data to server:
xdr.send();

xdr.onload=function(){var data=JSON.parse(xdr.responseText);};

XDomain支持的方法有onload,onerror,ontimeout,onprogress,timeout。

JSONP

JSONP(JSON with padding)很早之前就被标准化了,甚至在CORS之前。这是另一种从远程服务器抓取数据的方式。原理是通过创建一个script标签,所请求的外部文件包含一段JSON数据,数据是由服务器所返回的,作为参数包装在一个函数调用中。script标签获取脚本文件并不受跨域的限制,所有浏览器都支持这种技术。

下面的例子是一个script标签指向一个远程服务:

<script src="http://example.com/data.json"></script>

所请求的文件data.json中包含一个JSON对象,这个对象包装在一个函数调用中:

jsonCallback({"data":"foo"})

这时我们定义一个全局函数,当加载脚本后,这个函数就会被调用:

window.jsonCallback=function(result){

//处理返回结果的相关逻辑

}

jQuery将这个过程包装成了简洁API:

jQuery.getJSON("http://example.com/data.json?callback=jsonCallback",function(result){
console.log(result);
});

或者

  $.ajax({
        url:"http://crossdomain.com/services.php",
        dataType:‘jsonp‘,
        data:‘‘,
        jsonp:‘callback‘,
        success:function(result) {
        },
        timeout:3000
    }); 

jQuery将上面的URL中最后的问号替换为一个由它创建的随机命名的临时函数。服务器会获取这个callback参数,使用这个名字作为回调函数名称返回给客户端。

参考资料:

《基于MVC的Javascript Web富应用开发》

http://msdn.microsoft.com/zh-cn/library/dd573303%28v=vs.85%29.aspx

跨域请求详解

时间: 2024-10-28 19:12:22

跨域请求详解的相关文章

AJAX请求和跨域请求详解(原生JS、Jquery)

一.概述 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新.传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面. 本博客实验环境: python:2.7.11 web框架:tonado jquery:2.1.1 二.“伪”AJAX 由于

jQuery jsonp跨域请求详解

跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制的. 浏览器的同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互. 如果协议,端口和主机对于两个页面是相同的,则两个页面具有相同的源,否则就是不同源的. 如果要在js里发起跨域请求,则要进行一些特殊处理了.或者,你可以把请求发到自己的服务端,再通过后台代码发起请求,再将数据返回前端. 这里讲下使用jquery的jsonp如何发起跨域请求及其原理. 先看下准备环境:两个端口不一样,构成跨域请求的条件. 获取数据:获取数据

jsonp 跨域原理详解

JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略).这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容. JavaScript这个安全策略在进行多iframe或多窗口编程.以及Ajax编程时显得尤为重要.根据这个策略,在baidu.com下的页面中包含的JavaScript代码,不能访问在

你不知道的jQuery Item11 -- ajax jsonp跨域方法详解

文章从JSON和JSONP区别开始讲起,用实例来对比他们之间的不同之处,然后详细讲解了jQuery中的ajax jsonp的使用并给出了示例及详细参数说明. 1.JSON和JSONP JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在浏览器和服务器之间交换信息. JSONP(JSON With Padding),就是打包在函数调用中的的JSON(或者包裹的JSON),你要跨域请求别人的东西,你肯定要包裹起来,不要污染了别人的东西,把Json数据包裹

跨域问题详解

在JavaScript中,有一个很重要的安全性限制,被称为"Same-Origin Policy"(同源策略).这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容. ??跨越是浏览器进行安全限制的一种方法,如果浏览器禁用了这种安全限制就不会出现跨域问题产生跨域的原因(以下三者都满足): 只要调用方访问被调用方的域名.端口.IP不一样 浏览器没有禁用安全限制 采用了XMLHttpRequest的请求 Jav

ajax请求总是不成功?浏览器的同源策略和跨域问题详解

场景 码农小明要做一个展示业务数据的大屏给老板看,里面包含了来自自己网站的数据和来自隔壁老王的数据.那么自己网站的数据提供了 http://xiaoming.com/whoami 这样的数据接口隔壁老王提供了 http://oldwang.com/isdad 这样的数据接口单独点开都是没有问题的.但是一使用 js 的 ajax 请求就无法收到来自 oldwang.com 的数据了.点开浏览器控制台一看,红字标出(Chrome): XMLHttpRequest cannot load http:/

在ASP.NET 5应用程序中的跨域请求功能详解

在ASP.NET 5应用程序中的跨域请求功能详解 浏览器安全阻止了一个网页中向另外一个域提交请求,这个限制叫做同域策咯(same-origin policy),这组织了一个恶意网站从另外一个网站读取敏感数据,但是一些特殊情况下,你需要允许另外一个站点跨域请求你的网站. 跨域资源共享(CORS:Cross Origin Resources Sharing)是一个W3C标准,它允许服务器放宽对同域策咯的限制,使用CORS,服务器可以明确的允许一些跨域的请求,并且拒绝其它的请求.CORS要比JSONP

AJAX(XMLHttpRequest)进行跨域请求方法详解(三)

注意:以下代码请在Firefox 3.5.Chrome 3.0.Safari 4之后的版本中进行测试.IE8的实现方法与其他浏览不同. 3,带验证信息的请求 身份验证是Web开发中经常遇到的问题,在跨域请求中,默认情况下是不发送验证信息的.要想发送验证信息,需要进行withCredentials 属性,下面就是一个简单请求的例子: [xhtml] view plaincopyprint? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transi

AJAX(XMLHttpRequest)进行跨域请求方法详解(二)

注意:以下代码请在Firefox 3.5.Chrome 3.0.Safari 4之后的版本中进行测试.IE8的实现方法与其他浏览不同. 2,预检请求 预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的.下面的2种情况需要进行预检:a,不是上面的简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求b,在请求中设置自定义头,比如 X-JSON.X-MENGXI