Ajax跨域

发布自 Kindem的博客,欢迎你们转载,可是要注意注明出处。另外,该文章收纳在 Kindem的我的的 IT 知识整理仓库,欢迎 Star、Fork、投稿

Ajax跨域简介

所谓Ajax跨域指的是Ajax请求从其余的域获取数据或者传输数据html

所谓域同源,指的是两个服务器资源的根url域名端口协议三者彻底相同,只要三者中任何一个不一样,则说明产生了跨域前端

给一个例子,对于第一个服务器资源,其余一些url的同源状况以下:java

http://www.test.com/index.html

http://www.test.com/index.js            同源
http://www.test.com/login/login.js      同源
https://www.test.com/index.html         跨域(协议)
http://www.a.com/index.html             跨域(域名)
http://a.com/index.html                 跨域(不一样子域)
http://www.test.com:8080/index.html     跨域(端口)

经常使用跨域方法

CORS

CORS是一个W3C标准,其全称为Cross-Origin Resource Sharing,即跨域资源共享。它容许浏览器向跨域服务器发送XMLHttpRequest请求,从而克服了Ajax只能同源使用的限制git

CORS须要浏览器和服务器同时支持,目前主流浏览器都支持这个标准(IE>=10),因此CORS的关键主要在于服务器,要支持这个功能,每每开发者须要在服务器端进行额外设置github

另外,CORS标准对用户来讲是透明的,用户感知不到CORS的存在,一切都是浏览器自动完成。当浏览器检测到跨域的Ajax请求时,就会自动作出一些处理,使得请求可以跨域ajax

跨域的Ajax请求分为两种:json

  • 简单请求:跨域

    • 请求方法为HEADPOSTGET之一
    • HTTP头字段只有AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type中的一种或多种
    • HTTP头字段中的Content-Type字段的取值为application/x-www-form-urlencodedmultipart/form-datatext/plain之一
  • 非简单请求: 全部不知足上述规则的请求

CORS对于两种不一样的请求的处理是不一样的浏览器

对于简单请求,一个跨域Ajax请求的处理流程以下:

  1. 浏览器自动在本次请求的HTTP头中添加Origin字段,表示此次请求来自的域
  2. 服务器根据Origin字段判断这一次请求是否在许可范围内:

    • 若是不在,返回一个正常的HTTP响应,只不过响应的HTTP头中没有Access-Control-Allow-Origin字段,浏览器将认为这一次跨域Ajax没能成功
    • 若是在,服务器会在响应HTTP头中添加这几个字段

      • Access-Control-Allow-Origin: 这个字段标识服务器认同的Origin,这个Origin*时标识服务器认同全部源。只有请求的HTTP头的Origin与该字段同源时,浏览器才会认为这一次跨域Ajax请求成功了
      • Access-Control-Allow-Credentials: 这个字段标识服务器容许Cookie,若是设置为true则标识容许,默认为不容许
      • Access-Control-Expose-Headers: 容许XMLHttpRequest获取的额外字段名

对于非简单请求,一个跨域Ajax请求的处理流程以下:

  1. 浏览器在发送正式的Ajax请求以前,会提早发送一次OPTIONS请求,头信息中有:

    • Origin: 请求的源
    • Access-Control-Request-Method: 浏览器会用的的HTTP方法
    • Access-Control-Request-Headers: 浏览器会额外发送的头信息字段
  2. 收到这个请求以后,服务器将会返回一些控制信息,最重要的仍然是上面说到的断定是否容许跨域的Access-Control-Allow-Origin
  3. 若是服务器返回了一个正常的HTTP响应,则浏览器会认为OPTIONS请求成功,接下来则会进行真正的的请求
  4. 服务器正常处理真正的请求,而且在返回的HTTP响应中也带上Access-Control-Allow-Origin,浏览器会再一次校验这一字段

可见CORS标准自己并不复杂,其核心是服务器和浏览器验证域是否被容许

JSONP

JSONP的全称为JSON with Padding,是JSON数据的一种使用模式,JSONP一样是为了支持跨域Ajax请求而生的,可是它相对CORS来讲对古老的浏览器兼容性较好,也更加简单。

JSONP的原理是JavaScript注入,在html中使用<script>标签引入JavaScript脚本是不会受到同源限制的,这意味着能够经过<script>标签引入来自跨域的脚本,像这样:

// origin:  http://www.test.com

<script>
    function dealData(jsonData) {
        // do something with jsonData
    }
</script>
<script src="http://www.a.com/data.js"></script>

想象一下若是引入的脚本是这样的:

dealData({
    username: 'kindem',
    age: 15,
    // ...
});

不是就至关于从服务器拿到一段数据而且进行处理了吗?

接下来能够设想一下,假设服务器对于src指向的url的处理并非返回一个静态文件,而是动态地组合出一段文本,这段文本一上面给的形式返回,里面的参数由服务器动态生成,而调用的函数则是前端约定好的函数,则至关于变相地返回了一段跨域的数据,这就是JSONP的核心思想

相关文章
相关标签/搜索