Ajax高级笔记 JavaScript高级程序设计笔记


Posted in Javascript onJune 22, 2017

Ajax通信与数据格式无关,从服务器获取的数据不一定是XML数据。

Ajax的核心:XMLHttpRequest对象(简称XHR)

在XHR对象之前,Ajax通信通常使用hack手段,如使用隐藏的或内嵌的框架。

XHR对象为向服务器发送信息和解析服务器响应提供了流畅的接口。

1.XMLHttpRequest对象

IE5是第一款引进XHR对象的浏览器,通过MSXML库中的ActiveX对象实现(有3个版本)。

兼容所有浏览器,创建XHR对象:

function createXHR(){
  if (typeof XMLHttpRequest != "undefined"){
    return new XMLHttpRequest();
  } else if (typeof ActiveXObject != "undefined"){
    if (typeof arguments.callee.activeXString != "string"){
      var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
              "MSXML2.XMLHttp"],
        i, len;
  
      for (i=0,len=versions.length; i < len; i++){
        try {
          new ActiveXObject(versions[i]);
          arguments.callee.activeXString = versions[i];
          break;
        } catch (ex){
          //skip
        }
      }
    }
  
    return new ActiveXObject(arguments.callee.activeXString);
  } else {
    throw new Error("No XHR object available.");
  }
}

之后就能在所有浏览器创建XHR对象:var xhr = createrXHR();

2.原生XHR对象 (支持的浏览器: IE7+、FF、Chrome、Opera、Safari)

通过XMLHttpRequest构建函数,创建XHR对象:

var xhr = new XMLHttpRequest();

3.XHR用法

3-1.open()

open() 3个参数: 发送的类型、请求的URL、表是否异步的布尔值

xhr.open("get","example.php", false);

①URl为相对于执行代码的当前页,或绝对地址;

②false为同步,JavaScript代码会在服务器响应后再继续执行;

③调用open()只是启动一个请求以备发送,还没真正发送;

④只能在同个域中使用相同端口和协议的URL发送请求。

3-2.send()

send() 1个参数: 请求主体发送的数据,不需要通过请求主体发送数据则传入null。

调用send()后,请求被分派到服务器。

xhr.open("get","example.php", false) ;
xhr.send(null);

3-3. 收到响应后,响应数据会自动填充XHR对象的属性:

responseText:作为响应的主体被返回的文本;

responseXML:若响应的内容类型”text/xml”或”application/xml”,此属性保存响应数据XML DOM文档

status:响应的HTTP状态;

statusText:HTTP状态的说明。

☆:无论什么内容类型,响应主体的内容都会保存在responseText属性中。对于非XML数据,responseXML属性值为null。
3-4.status属性确认响应是否成功返回

HTTP状态代码:

200:响应有效,responseText属性已就绪,内容类型正确下的responseXML也可访问。

304:响应有效,只是请求的资源并为修改,可直接使用浏览器中缓存的版本。

正确检查上述2种状态代码:

status判断

if ((xhr.status >= 200 && xhr.status <=300) || xhr.status == 304) {
   alert(xhr.responseText);
} else {
   alert("Request was unsuccessful:" + xhr.status);
};

3-5.readystate属性

该属性存储 请求/响应过程的 当前活动状态。

0 : 未初始化,未调用open();
1 : 启动,调用了open();
2 : 发送,调用了send(),未接受响应;
3 : 接受,已接受部分响应;
4 : 完成,已接受全部响应,且可在客户端使用。

3-6.readystatechange事件

该事件,在readystate属性值改变时触发。

readystatechange事件句柄

var xhr = createXHR();
xhr.onreadystatechange = function(event){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("get", "example.txt", true);
xhr.send(null);

①必须在调用open()之前知道readystatechange事件的事件处理程序,确保兼容。

②该事件处理程序中没有传递event对象,必须通过XHR对象本地来确定下一步怎么做;

③使用xhr对象而不使用this对象,是因为onreadystatechange事件处理程序的作用域问题。使用this对象在一些浏览器会导致函数执行失败或发生错误。

3-7.abort()

调用此方法可取消异步请求:xhr.abort();

调用后,xhr对象停止触发事件,不允许访问如何与响应相关的属性;

终止请求后,应对XHR对象进行解引用操作,不建议重用XHR对象。

4、HTTP头部信息

发送请求时的头部信息:

Accept:浏览器能够处理的内容类型

Accept-Charset:浏览器能够显示的字符集

Accept-Encoding:浏览器能够处理的压缩编码

Axxept-Language:浏览器当前设置的语言

Connection:浏览器与服务器之间连接的类型

Cookie:当前页面设置的如何Cookie

Host:发送请求耳洞页面所在域

Referer:发出请求的页面的URI

User-Agent:浏览器的用户代理字符串

setRequestHeader()

设置自定义头部信息。

2个参数:头部字段名称、头部信息值。

需在open()方法之后调用send()之前调用setRequestHeader(),才能成功发送请求头部信息。

自定义HTTP头部信息

var xhr = createXHR();    
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("get", "example.php", true);
xhr.setRequestHeader("MyHeader", "MyValue");
xhr.send(null);

getRequestHeader()

获取指定的相应头部信息

xhr.getRequestHeader(“MyHeader”);
getAllRequestHeader()

获取一个包含所有头部信息的长字符串

xhr.getAllRequestHeader();

5、GET请求

对于XHR对象,位于opne()的URL末尾的查询字符串 需经过编码,使用encodeURIComponent()编码。

名-值对需用和号(&)分隔。

自定义函数,添加URL查询字符串参数:

function addURLParam(url,name,value){
  url += (url.indexOf('?') == -1?'?':'&');
  url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
  return url;
}

6、POST请求

长用于想服务器发送要保存的数据。

由于XHR其初的设计是为了处理XML,故在send(0中可传入XHR DOM文档。

6-1.服务端读取POST数据

①默认情况下,服务器对POST请求和提交Web表单不会一视同仁,故服务端需要程序来读取发送的原始数据,并解析出有用部分。

②XHR模拟表单提交:

1.将Content-Type头部信息设置为application/x-www-form-urlencoded (即表单提交时的内容问题);

2.以适当格式创建一个字符串。(通过serialize()函数创建该字符串,序列化表单数据)

XHR模拟表单提交

function submitData(){
  var xhr = createXHR();    
  xhr.onreadystatechange = function(event){
    if (xhr.readyState == 4){
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
        alert(xhr.responseText);
      } else {
        alert("Request was unsuccessful: " + xhr.status);
      }
    }
  };

  

  xhr.open("post", "postexample.php", true);
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  var form = document.getElementById("user-info");      
  xhr.send(serialize(form));
}

 7、CORS 跨源资源共享(IE8+、FF、Chrome....)

跨域安全策略限制了Ajax的异步通信,CORS则是定义了跨域时,客户端和服务器的沟通。

CORS思想:使用自定义HTTP头部让浏览器与服务器进行沟通,从而决定请求/响应的成功与否。

7-1.给一个请求附加Origin头部,包含请求页面的源信息(协议、域名 和 端口)

Origin: http://www.domain.com

服务器根据Origin判断是否接收请求,接收则在Access-Control-Allow-Origin头部会发相同信息。

(若是公共资源,可以回发"*")

Access-Control-Allow-Origin: http://www.domain.com

若无此头部或头部信息不匹配,浏览器将驳回请求。

☆请求和响应不会包含cookie信息。

7-2.IE8+对CORS的实现

IE8引入的XDR(XDomainRequest)类型,类型XHR,可实现安全可靠的跨域通信。

7-2-1.XDR与XHR的不同之处:

①cookie不会随请求发送,也不会随响应返回;

②只能设置请求头部信息中的Content-Type字段;

③不能访问响应头部信息;

④只支持GET和POST请求

XDR缓解了CSRF(跨站请求伪造)和XSS(跨站点脚本)问题

被请求的资源可判断用户代理、来源页面等如何数据 来决定是否设置Access-Control-Allow-Origin头部

7-2-2. XDR使用方法类似XHR,创建一个XDomainRequest实例,调用open(),再调用send()。

XDR只能执行异步请求,所以open()方法只有两个参数,请求的类型和URL。

在收到响应后,只能访问响应的原始文本,无法确定响应的状态代码。

只要响应有效就会触发load事件,响应的数据会保存在responseText属性中。

如果失败(如,响应中缺少Access-Control-Allow-Origin头部)就会触发error事件,但该事件无有用信息,需要自定义一个onerror事件句柄。

obload事件-onerror事件

var xdr = new XDomainRequest();
xdr.onload = function(){
  alert(xdr.responseText);
};
xdr.onerror = function(){
  alert("Error!");
};

xdr.open("get", "http://www.somewhere-else.com/xdr.php");
xdr.send(null);

在请求返回前调用abort()可终止请求。

7-2-3.XDR也支持timeout属性及ontiomout事件处理程序,在运行超过timeout设定的秒数后,调用ontimeout事件句柄。

为支持POST请求,XDR提供了contentType属性,用于表示发送数据的格式。

contentType属性是XDR对象影响头部信息的唯一方式。

xdr.contentType = "application/x-www-form-urlencoded";

7-3其他浏览器对CORS的实现

FF等浏览器都通过XMLHttpRequest对象实现了对CORS的原生支持。要请求另一个域中的资源时,使用标准XHR对象并在open()中传入绝对URL即可。

标准XHR的跨域

var xhr = createXHR();    
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4){
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      alert(xhr.responseText);
    } else {
      alert("Request was unsuccessful: " + xhr.status);
    }
  }
};
xhr.open("get", "http://www.abc.com/page/", true);
xhr.send(null);

与IE不同,通过跨域XHR对象可以访问status属性和statusText属性,也可同步请求。

7-3-1.跨域XHR的限制:

①不能使用setRequestHeader()设置自定义头部;

②不能发送和接收cookie;

③调用getAllResponseHeader()方法总会返回空字符串。

7-3-2.无论同源请求还是跨域请求都是使用相同的接口,故对于本地资源,最好用相对URL,对远程资源再用绝对URL。

这样能消除歧义,避免出现限制访问头部或本地cookie信息等问题。

7-4、跨浏览器的CORS(IE8+、FF等)

检测XHR是否支持CORS的方法:检查是否存在withCredentials属性,在结合检测XDomainRequest对象是否存在。

CORS跨域兼容

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.somewhere-else.com/xdr.php");
if (request){
  request.onload = function(){
    //do something with request.responseText
  };
  request.send();
}

上述createCORSRequest()函数返回的对象的属性(XHR和XDR的共同属性):

①abort():停止正在进行的请求;

②onerror:用于替代onreadystatechange检测错误;

③onload:用于代替onreadystatechange检测成功;

④responseText:用于取得响应内容;

⑤send():用于发送请求。

8、其他跨域技术

在CORS出现前,常利用DOM中能够执行跨域请求的功能,在不依赖XHR对象时,也能发送某种请求。

与COSR不同的是,不用修改服务器代码。

8-1.图像Ping

使用<img>标签,由于可以从任何网页加载图像,故常是在线广告跟踪浏览量的只要方式。

可动态创建图像,使用它们的onload和onerror事件句柄,确定是否接受到了响应。

var img = new Image();
img.onload = img.onerror = function(){
  alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";

图像Ping是与服务器进行简单、单向的跨域通信的一种方式。请求的数据通过查询字符串形式发送,响应可以是任何内容,通常是像素图或204响应。虽然通过图像Ping,浏览器得不到任何具体数据,但通过侦听load和error事件,能找到响应收到的时间。

图像Ping常用于跟踪用户点击页面 或动态广告曝光次数。

缺点:①只能发送GET请求;②无法访问服务器响应文本。

8-2.JSONP

JSONP(JSON width Padding)填充式JSON或参数式JSON,类似JSON,是包含在函数调用中的JSON:

callback( {"name" : "value"} );
8-2-1.JSONP有两个部分:回调函数 和 数据

回调函数:当响应到来时应该在页面中调用的函数。回调函数的名称在请求中指定。

数据:传入回调函数的JSON数据。

8-2-2.JSONP通过动态<script>元素,为其src属性指定一个跨域的URL。类似<img>元素,即都能不受限制地跨域加载资源。

JSONP为有效的JavaScript代码,在请求完成即JSONP响应 加载到页面后就会立即执行。

function handleResponse(response){
  alert("You're at IP address " + response.ip + ", which is in " + response.city + ", " + response.region_name);
}

var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

headleResponse()为回调函数,将在响应到来后执行。

8-2-3.JSONP之所以流行,是因为 :

①能够直接访问响应文本;

②支持浏览器与服务器之间的双向通信。

不足:

①JSONP从其他域加载代码执行,因此该域必须安全可靠;

②很难确保JSONP请求是否失败。

8-3Comet ”服务器推送" 【不兼容IE】

Ajax从页面想服务器请求数据,Comet则是服务器向页面推送数据,Comet能近乎实时地向页面推送信息。

8-3-1.实现Comet的2种方式:长轮询 和 流

①长轮询:与短轮询相反,页面发送一个请求,服务器一直保持连接打开,直到有数据可发送时就向页面发送数据。接收完数据后浏览器关闭连接,随机又发送一个新请求,在页面打开期间如此循环...

【短轮询是服务器立即发送数据,即使数据无效,长轮询是等待发送响应。】

轮询的优点是,所有浏览器都支持。通过XHR对象和setTimeout()实现。

②HTTP流:它在网页的整个生命周期内只使用一个HTTP连接。浏览器发送一个请求,服务器保持连接打开,再周期性向浏览器发送数据.

PHP例子

<?php
$i = 0;

while (true) {


//输出一些数据,然后刷新输出缓存


echo "Number is $1";


flush();



//等几秒


sleep(10);



$++;

}
...

实现HTTP流的关键:所有服务器端语言都支持打印到输出缓存然后刷新的功能。(将输出缓存中的内容一次性全部发送给客户端)

使用XHR实现HTTP流的典型例子

var xhr = new XMLHttpRequest(),
  received = 0;
  
xhr.open("get", url, true);
xhr.onreadystatechange = function(){
  var result;
  
  if (xhr.readyState == 3){
  
    //get only the new data and adjust counter
    result = xhr.responseText.substring(received);
    received += result.length;
    
    //call the progress callback
    progress(result);
    
  } else if (xhr.readyState == 4){
    finished(xhr.responseText);
  }
};
xhr.send(null);
return xhr;
}

var client = createStreamingClient("streaming.php", function(data){
      alert("Received: " + data);
     }, function(data){
      alert("Done!");
     });

以上就是三水点靠木小编为大家分享的Ajax高级笔记的相关内容,对于学习ajax的朋友应该是个不错的入门讲解。

Javascript 相关文章推荐
table行随鼠标移动变色示例
May 07 Javascript
让JavaScript的Alert弹出框失效的方法禁止弹出警告框
Sep 03 Javascript
JavaScript转换二进制编码为ASCII码的方法
Apr 16 Javascript
JavaScript6 let 新语法优势介绍
Jul 15 Javascript
php输出全部gb2312编码内的汉字方法
Mar 04 Javascript
Vue2.0 从零开始_环境搭建操作步骤
Jun 14 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
Sep 06 Javascript
浅谈react前后端同构渲染
Sep 20 Javascript
原生JS 实现的input输入时表格过滤操作示例
Aug 03 Javascript
浅谈小程序globalData的那些事儿
Nov 01 Javascript
24行JavaScript代码实现Redux的方法实例
Nov 17 Javascript
three.js欧拉角和四元数的使用方法
Jul 26 Javascript
vue 请求后台数据的实例代码
Jun 22 #Javascript
深入理解vue.js中的v-if和v-show
Jun 22 #Javascript
vue如何从接口请求数据
Jun 22 #Javascript
利用node.js制作命令行工具方法教程(一)
Jun 22 #Javascript
关于在vue-cli中使用微信自动登录和分享的实例
Jun 22 #Javascript
详解vue 配合vue-resource调用接口获取数据
Jun 22 #Javascript
vue使用stompjs实现mqtt消息推送通知
Jun 22 #Javascript
You might like
非常好用的Zend Framework分页类
2014/06/25 PHP
解决laravel查询构造器中的别名问题
2019/10/17 PHP
如何用js控制css中的float的代码
2007/08/16 Javascript
nodejs的10个性能优化技巧
2014/07/15 NodeJs
jQuery插件Tooltipster实现漂亮的工具提示
2015/04/12 Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
2015/08/18 Javascript
JavaScript设计模式初探
2016/01/07 Javascript
Javascript中常见的逻辑题和解决方法
2016/09/17 Javascript
微信小程序 label 组件详解及简单实例
2017/01/10 Javascript
Vue自定义指令详解
2017/07/28 Javascript
使用JavaScript实现链表的数据结构的代码
2017/08/02 Javascript
解决IOS端微信H5页面软键盘弹起后页面下方留白的问题
2019/06/05 Javascript
webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法
2019/06/28 Javascript
使用JS location实现搜索框历史记录功能
2019/12/23 Javascript
JavaScript 中判断变量是否为数字的示例代码
2020/10/22 Javascript
WebStorm中如何将自己的代码上传到github示例详解
2020/10/28 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
2021/01/20 Vue.js
python中执行shell的两种方法总结
2017/01/10 Python
python3+PyQt5泛型委托详解
2018/04/24 Python
Python创建一个空的dataframe,并循环赋值的方法
2018/11/08 Python
10行Python代码计算汽车数量的实现方法
2019/10/23 Python
美国非常受欢迎的Spa品牌:Bliss必列斯
2018/04/10 全球购物
char型变量中能不能存贮一个中文汉字
2015/07/08 面试题
.NET程序员的几道面试题
2012/06/01 面试题
几道Web/Ajax的面试题
2016/11/05 面试题
经典的班主任推荐信
2013/10/28 职场文书
丧事主持词大全
2014/04/02 职场文书
如何签定毕业生就业协议书
2014/09/28 职场文书
九九重阳节标语
2014/10/07 职场文书
教师思想作风整顿个人剖析材料
2014/10/10 职场文书
应届毕业生求职简历自我评价
2015/03/02 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书
责任书格式
2019/04/18 职场文书
2019中秋节祝福语大全,提前收藏啦
2019/09/10 职场文书
为什么MySQL分页用limit会越来越慢
2021/07/25 MySQL
十大最强水系宝可梦,最美宝可梦排第三,榜首大家最熟悉
2022/03/18 日漫