XHR对象只能访问与包含它的页面位于同一个中的资源。这种安全策略可以预防某些恶意行为。
CORS(Cross-Origin Resource Sharing,跨域资源共享)是W3C的一个工作草案,定义了在必须访问跨域资源时,浏览器与服务器应该如何沟通。CORS基本思想:使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
如:一个使用GET或POST发送的请求,没有自定义的头部,主体内容是text/plain。发送请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的源信息(协议、域名和端口),以便服务器根据这个头部信息来决定是否给与响应。

Origin头部如:
Origin: http://www.nczonline.net
若服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息(若是公共资源,可以回发“*”)。如:
Access-Control-Allow-Origin: http://www.nczonline.net
若没有这个头部,或有这个头部但源信息不匹配,浏览器就会驳回请求。正常情况下,浏览器会处理请求。
注:请求和响应都不包含cookie信息。

1、IE对CORS的实现
微软在IE8中引入了XDR(XDomainRequest)类型,能够实现安全可靠的跨域通信。XDR对象的安全机制部分实现了W3C的CORS规范。
XDR与XHR的一些不同之处
* cookie不会随请求发送,也不会随响应返回。
* 只能设置请求头部信息中的Content-Type字段。
* 不能访问响应头部信息。
* 只支持GET和POST请求。
被请求的资源可以根据它认为合适的任意数据(用户代理、来源页面等)来决定是否设置Access-Control-Allow-Origin头部。作为请求的一部分,Origin头部的值表示请求的来源域,以便远程资源明确的识别XDR请求。
XDR对象的使用方法与XHR对象非常相似。也是创建一个XDomainRequest的实例,调用open()方法,再调用send()方法。但与XHR对象的open()方法不同,XDR对象的open()只接收2个参数:请求的类型和URL。
所有XDR请求都是异步执行的。请求返回之后,会触发load事件,响应的数据也会保存在responseText属性中,如:
var xdr = new XDomainRequest();
xdr.onload = function(){
alert(xdr.responseText);
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null);

在接收到响应后,只能访问响应的原始文件,没有办法确定响应的状态代码。而且只要响应有效就会触发load事件,如果失败就会触发error事件。遗憾的是,除了错误本身之外,没有其他信息可用,因此唯一能够确定的就只有请求未成功了。要检测错误,可以指定一个onerror事件处理程序:
var xdr = new XDomainRequest();
xdr.onload = function(){
alert(xdr.responseText);
};
xdr.onerror = function(){
alert("An error occurred.");
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null);

注:导致XDR请求失败的因素很多,所以建议通过onerror事件处理程序来捕获该事件;否则,即使请求失败也不会有任何提示。

在请求返回前调用abort()方法可以终止请求:
xdr.abort(); //终止请求
XDR对象也支持timeout属性以及ontimeout事件处理程序。如:
var xdr = new XDomainRequest();
xdr.onload = function(){
alert(xdr.responseText);
};
xdr.onerror = function(){
alert("An error occurred.");
};
xdr.timeout = 1000;
xdr.ontimeout = function(){
alert("Request took too long.");
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null);
运行1s后超时,并随机调用ontimeout事件处理程序。

为支持POST请求,XDR对象提供了contentType属性,用来表示发送数据的格式,如:
 1   var xdr = new XDomainRequest();
2 xdr.onload = function(){
3 alert(xdr.responseText);
4 };
5 xdr.onerror = function(){
6 alert("An error occurred.");
7 };
8 xdr.open("post", "http://www.somewhere-else.com/page/");
9 xdr.contentType = "application/x-www-form-urlencoded";
10 xdr.send("name1=value1&name2=value2");
这个属性是通过XDR对象影响头部信息的唯一方式。

2、其他浏览器对CORS的实现

 1 var xhr = createXHR();
2 xhr.onreadystatechange = function(){
3 if(xhr.readyState ==4){
4 if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
5 alert(xhr.responseText);
6 }else{
7 alert("Request was unsuccessful: " + xhr.status);
8 }
9 }
10 };
11 //跨域请求的url为绝对的链接
12 xhr.open("get", "http://www.somewhere-else.com/page/", true);
13 xhr.send(null);
限制:
* 不能使用setRequestHeader()设置自定义头部。
* 不能发送和接收cookie。
* 调用getAllResponseHeaders()方法总会返回空字符串。

对于本地资源,最好使用相对URL,访问远程资源时使用绝对URL,可以消除歧义,避免出现限制访问头部或本地cookie信息等问题。
3、跨浏览器的CORS
所有浏览器都支持简单的(非Preflight和不带凭据的)请求,因此有必要实现一个跨浏览器的方案。

 1 function createCORSRequest(method, url){
2 var xhr = new XMLHttpRequest();
3 if("withCredentials" in xhr){
4 xhr.open(method, url, true);
5 }else if(typeof XDomainRequest != "undefined"){
6 xhr = new XDomainRequest();
7 xhr.open(method, url);
8 } else {
9 xhr = null;
10 }
11 return xhr;
12 }
13 var request = cresteCORSRequest("get", "http://www.somewhere-else.com/page/");
14 if(request){
15 request.onload = function(){
16 //对request.responseText进行处理
17 };
18 request.send();
19 }
Firefox、Safari、Chrome中的XMLHttpRequest对象与IE中的XDomainRequest对象类似,都提供了够用的接口,因此以上模式还是相当有用的。
这两个对象共同的属性/方法如下:
* abort():用于停止正在进行的请求。
* onerror:用于替代onreadystatechange检测错误。
* onload:用于替代onreadystatechange检测成功。
* responseText:用于取得相应内容。
* send():用于发送请求。
以上成员都包含在createCORSRequest()函数返回的对象中,在所有浏览器中都能正常使用。

Javascript Ajax总结——跨域资源共享的更多相关文章

  1. javascript ajax 脚本跨域调用全解析

    javascript ajax 脚本跨域调用全解析 今天终于有点时间研究了一下javsscript ajax 脚本跨域调用的问题,先在网上随便搜了一下找到一些解决的办法,但是都比较复杂.由是转到jqu ...

  2. AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比----转载

    1 前言: 首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源.本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源-同源策略:其次,介 ...

  3. 跨域资源共享(CORS)--跨域ajax

    几年前,网站开发者都因为ajax的同源策略而撞了南墙.当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访 ...

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

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

  5. JavaScript(10)——Ajax以及跨域处理

    Ajax以及跨域处理 哈哈哈,终于写到最后一章了.不过也还没有结束,说,不要为了学习而学习,恩.我是为了好好学习而学习呀.哈哈哈.正在尝试爱上代码,虽然有一丢丢的难,不过,我相信我会的! [Ajax] ...

  6. django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享

    一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...

  7. Ajax及跨域

    概念 Ajax Ajax,Asynchronous JavaScript and XML,字面意思:异步的 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术. 用于异步地去获 ...

  8. AJAX POST&跨域 解决方案 - CORS

    一晃又到新年了,于是开始着手好好整理下自己的文档,顺便把一些自认为有意义的放在博客上,记录成点的点滴.          跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是 ...

  9. PhoneGap开发跨平台移动APP - 解决跨域资源共享

    解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...

  10. [CORS:跨域资源共享] 同源策略与JSONP

    Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...

随机推荐

  1. 【Azure Batch】在批处理的Task中如何让它执行多个CMD指令呢

    问题描述 根据Azure Batch的入门文档(使用 Azure 门户创建 Batch 帐户并运行作业 : https://docs.azure.cn/zh-cn/batch/quick-create ...

  2. 你知道Golang的模板怎么用吗?带你了解动态文本的生成!

    Golang Template Go语言中的Go Template是一种用于生成文本输出的简单而强大的模板引擎.它提供了一种灵活的方式来生成各种格式的文本,例如HTML.XML.JSON等. Go T ...

  3. WebAssembly实践指南——C++和Rust通过wasmtime实现相互调用实例

    C++和Rust通过wasmtime实现相互调用实例 1 wasmtime介绍 wasmtime是一个可以运行WebAssembly代码的运行时环境. WebAssembly是一种可移植的二进制指令集 ...

  4. Github、Gitee优秀的开源项目

    收集 Github.Gitee优秀的开源项目,并进行归类整理.项目地址 目录 编程语言项目 SprinBoot 项目 源码分析项目 前后端分离项目 Vue2 项目 Vue3 项目 微服务项目 Api ...

  5. 千呼万唤始出来 JDK 21 LTS, 久等了

    平地起惊雷!!! 目录 英雄的迟暮 大人时代变了 JDK 21 LTS 前 JAVA并发编程模型 JDK 21 LTS 中的 JAVA 并发编程模型 虚拟线程 VS 线程池 The Last 你可以称 ...

  6. 两种方式,创建有返回值的DB2函数

    函数场景:路径信息由若干个机构编码组成,且一个机构编码是9位字符. 要求:获取路径信息,并且删除路径中包含'99'开头的机构编码. 从客户端及服务器端分别创建ignore99(pathinfo var ...

  7. 使用django 定时任务 (Django + celery + beat )

    安装 django + celery + results https://www.cnblogs.com/lanheader/p/13615772.html 安装 django-celery-beat ...

  8. P5404 [CTS2019] 重复 题解

    题目链接 观察题目,我们发现直接计算是困难的,先构造单个合法的 \(T\) 分析其性质. 为了构造出 \(T\),先考虑构造时 \(T\) 时什么时候会出现不合法的情况,此时 \(T\) 会有一段和 ...

  9. Mybatis-plus 生成代码

    引入依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-g ...

  10. cookie、session、web storage

    cookie与session的区别 首先,使用cookie和session的目的都是为了跟踪记录用户状态,因为http协议是无状态的协议,而某些场景服务端需要记录用户的状态,如购物车,需要来识别具体的 ...