Javascript Ajax总结——跨域资源共享
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总结——跨域资源共享的更多相关文章
- javascript ajax 脚本跨域调用全解析
javascript ajax 脚本跨域调用全解析 今天终于有点时间研究了一下javsscript ajax 脚本跨域调用的问题,先在网上随便搜了一下找到一些解决的办法,但是都比较复杂.由是转到jqu ...
- AJAX学习笔记2:XHR实现跨域资源共享(CORS)以及和JSONP的对比----转载
1 前言: 首先对参考文章作者表示感谢,你们的经验总结给我们这些新手提供了太多资源.本文致力于解决AJAX的CORS问题,我在逻辑上进行了梳理:首先,系统的总结了CORS问题的起源-同源策略:其次,介 ...
- 跨域资源共享(CORS)--跨域ajax
几年前,网站开发者都因为ajax的同源策略而撞了南墙.当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访 ...
- AJAX跨域资源共享 CORS 详解
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
- JavaScript(10)——Ajax以及跨域处理
Ajax以及跨域处理 哈哈哈,终于写到最后一章了.不过也还没有结束,说,不要为了学习而学习,恩.我是为了好好学习而学习呀.哈哈哈.正在尝试爱上代码,虽然有一丢丢的难,不过,我相信我会的! [Ajax] ...
- 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 ...
- Ajax及跨域
概念 Ajax Ajax,Asynchronous JavaScript and XML,字面意思:异步的 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术. 用于异步地去获 ...
- AJAX POST&跨域 解决方案 - CORS
一晃又到新年了,于是开始着手好好整理下自己的文档,顺便把一些自认为有意义的放在博客上,记录成点的点滴. 跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是 ...
- PhoneGap开发跨平台移动APP - 解决跨域资源共享
解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...
- [CORS:跨域资源共享] 同源策略与JSONP
Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...
随机推荐
- 如何理解SpringBoot的Starter
Starter是SpringBoot的四大核心功能特性之一,除此之外,SpringBoot还有自动装配,Actuator监控等特性 SpringBoot里面的这些特性,都是为了让开发者在开发基于Spr ...
- 记一次 .NET 某拍摄监控软件 卡死分析
一:背景 1. 讲故事 今天本来想写一篇 非托管泄露 的生产事故分析,但想着昨天就上了一篇非托管文章,连着写也没什么意思,换个口味吧,刚好前些天有位朋友也找到我,说他们的拍摄监控软件卡死了,让我帮忙分 ...
- Python网络编程——TCP套接字通信、通信循环、链接循环、UDP通信
文章目录 基于TCP的套接字通信 加上通信循环 加上链接循环 基于UDP协议的套接字通信 基于TCP的套接字通信 以买手机的过程为例 服务端代码 import socket # 1.买手机 phone ...
- Face to Face with Hurricane Camille
1.Face to Face with Hurricane Camille Joseph P. Blank 1 John Koshak, Jr., knew that Hurricane Camill ...
- 【开源】给ChatGLM写个,Java对接的SDK
作者:小傅哥 - 百度搜 小傅哥bugstack 博客:bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 大家好,我是技术UP主小傅哥. 清华大学计算机系的超大规模训练模型 Cha ...
- 2023-10-14:用go语言,给定 pushed 和 popped 两个序列,每个序列中的 值都不重复, 只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时, 返回
2023-10-14:用go语言,给定 pushed 和 popped 两个序列,每个序列中的 值都不重复, 只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时, 返回 ...
- 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能
开发板:STM32F407ZGT6: 目标:想使用软件"串口调试助手" 情况:开发板上的USB_UART口所在器件损坏或者直接没有: 解决办法:查看该开发板的原理图,可得:串口1的 ...
- Go 如何实现多态
在 Go 语言中,虽然没有经典的面向对象编程中的继承和多态的概念,但你可以通过接口(interface)来实现多态性.Go 语言鼓励组合和接口多态,这使得代码更加灵活和模块化.下面将详细介绍 Go 语 ...
- 文心一言 VS 讯飞星火 VS chatgpt (123)-- 算法导论10.4 4题
四.用go语言,对于一个含 n个结点的任意有根树,写出一个 O(n)时间的过程,输出其所有关键字该树以左孩子右兄弟表示法存储. 文心一言: 在计算机科学中,左孩子右兄弟表示法是一种用于表示树状结构的方 ...
- Chromium Canvas工作流
blink 中实现了2种 canvas,分别是 blink::HTMLCanvasElement 和 blink::OffscreenCanvas ,前者对应 html/dom 中的 canvas,后 ...