前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!

  AJAX 是 asynchronous javascript and XML 的简写,就是异步的 javascript 和 XML。这一技术能够向服务器请求额外的数据而无须刷新整个页面,会带来更好的用户体验。虽然名字中包含 XML,但是 ajax 通信与数据格式无关;

创建对象

  因为 XMLHTTPRequest() 是一个构造函数,所以需要实例化一个 XMLHttpRequset 对象。下面是创建XHR对象的兼容写法;

  如果要建立多个不同的请求,就要实例化多个不同的 XMLHttpRequset 对象;

  1. <script type="text/javascript">
  2. var xhr;
  3. if(window.XMLHttpRequest){
  4. xhr = new XMLHttpRequest();
  5. }else{
  6. xhr = new ActiveXObject('Microsoft.XMLHTTP');
  7. }
  8. </script>

发送请求

  要想把请求发送到服务器,我们就需要使用 open() 方法和 send() 方法。

open()

  open() 方法需要三个参数:

  1.        xhr.open("GET","test.json",true);

  第一个参数定义发送请求所使用的方法("GET" 还是 "POST"),不区分大小写,但通常使用大写字母,记得带引号。

  "GET" 用于常规请求,它适用于当 URL 完全指定请求资源,当请求对服务器没有任何副作用以及当服务器的响应是可缓存的情况下。

  然而,在以下情况中,请使用 "POST" 请求:

  • 无法使用缓存文件(更新服务器上的文件或数据库)
  • 向服务器发送大量数据("POST" 没有数据量限制)
  • 发送包含未知字符的用户输入时,"POST" 比 "GET"更稳定也更可靠

  第二个参数规定服务器端脚本的 URL(该文件可以是任何类型的文件,比如 .txt 和 .xml,或者服务器脚本文件,比如 .asp 和 .php (在传回响应之前,能够在服务器上执行任务)。

  第三个参数规定是否异步发送请求的布尔值,如果不填写,默认为 true,表示异步发送。如果接受的是同步响应,则需要将 open()方法的第三个参数设置为 false,那么 send()方法将阻塞直到请求完成。客户端 javascript 是单线程的,当 send() 方法阻塞时,它通常会导致整个浏览器界面冻结。如果连接的服务器响应慢,那么用户的浏览器将冻结,所以应该避免使用同步。

send()

  send() 方法接收一个参数,即要作为请求主体发送的数据。调用 send() 方法后,请求被分派到服务器。

  如果是 "GET" 方法,send() 方法无参数,或参数为 null;如果是 "POST" 方法,send() 方法的参数为要发送的数据。

  1. xhr.open("GET","test.json",false);
  2. xhr.send(null);

GET

  "GET" 用于常规请求,它适用于当 URL 完全指定请求资源,当请求对服务器没有任何副作用以及当服务器的响应是可缓存的情况下。

  【数据发送】

  使用 "GET" 方式发送请求时,数据被追加到 open() 方法中 URL 的末尾,可以直接看到,存在安全隐患。

  数据以问号开始,名和值之间用等号链接,名值对之间用和号(&)分隔。使用 "GET" 方式发送的数据常常被称为查询字符串。

  【编码】

  由于 URL无法识别特殊字符,所以如果数据中包含特殊字符(如中文),则需要进行编码,编码的方式有很多种,其中 encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。该方法主要对 ;/?:@&=+$,# 等这些用于分隔URI组件的字符以及中文进行编码。由于此方法对 :/ 都进行了编码,所以不能用它来对网址进行编码,而适合对 URI 中的参数进行编码

  在 "GET" 请求中,为了避免缓存的影响,可以向 URL 末尾添加一个随机数或时间戳。

  1. <script>
  2. var url = 'test.php' +'?name=' + encodeURIComponent("你好");
  3. xhr.open('GET',url+'&'+Number(new Date()),true);
  4. xhr.send(null);
  5. </script>

POST

  "POST" 请求通常用于向服务器发送应该被保存的数据。"POST" 方法常用于 HTML 表单。它在请求主体中包含额外数据且这些数据常存储到服务器上的数据库中。

  在 open() 方法第一个参数的位置传入"POST",就可以初始化一个 "POST" 请求。

  【设置请求头】

  默认情况下,服务器对 "POST" 请求和提交表单的请求并不会一视同仁。因此,服务器端必须有程序来读取发送过来的原始数据,并从中解析出有用的部分。不过,可以使用 XHR 来模仿表单提交:首先将 content-Type 头部信息设置为 application/x-www-form-urlencoded,也就是表单提交时的内容类型;

  使用 setRequestHeader() 方法可以设置自定义的请求头部信息。这个方法接受两个参数:头部字段的名称头部字段的值。要成功发送请求头部信息,必须在调用 open()方法之后且调用 send() 方法之前调用 setRequestHeader() 方法 。

  在项目中,又是需要验证用户登录,可以设置请求头验证。机制就是:在用户首次登录成功之后,服务器发送token到客户端,客户端存入cookie。用户做任何请求操作时,在 ajax的请求头里带上 token,用以 server-end 做登录状态验证。

  【发送主体】

  发送 "POST" 请求的第三步就是向 send() 方法中传入某些数据,这一点和 "GET" 请求不一样。由于 XHR 最初的设计主要是为了处理 XML,因此可以在此传入 XML DOM 文档,传入的文档经序列化之后将作为请求主体被提交到服务器。当然,也可以在此传入任何想发送到服务器的字符串。

  接下来要以适当的格式创建一个字符串,并使用 send() 方法发送。

  "POST" 数据的格式与 "GET" 数据的格式相同,名和值之间用等号链接,名值对之间用和号(&)分隔。

  【编码】

  由于使用 "POST" 方式传递数据时,需要设置请求头 "content-type",这一步骤已经能够自动对特殊字符(如中文)进行编码,所以就不再需要使用 encodeURIComponent() 方法了。

  "POST" 请求主要用于数据提交,相同 URL 的重复 "POST" 请求从服务器得到的响应可能不同,所以不应该缓存使用 "POST" 方法的请求。

  "GET" 对所发送信息的数量有限制,一般在2000个字符。与 "GET" 请求相比,"POST" 请求消耗的资源会更多一些。从性能角度来看,以发送相同的数据计,"GET" 请求的速度最多可"POST"请求的两倍。

  1. <script>
  2. xhr.open('POST',url,true);
  3. //设置请求头
  4. xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
  5. //拼接数据
  6. var strData = 'name="abc"&num=123';
  7. //发送请求
  8. xhr.send(strData);
  9. </script>

接收响应

  一个完整的 HTTP 响应由状态码、响应头集合和响应主体组成。

  在收到响应后,这些都可以通过 XMLHttpRequset 对象的属性和方法使用,主要有以下4个属性:

responseText 作为响应主体被返回的文本(文本格式)
responseXML 如果响应的内容类型是 "text/xml" 或 "application/xml",这个属性中将保存着响应数据的 XML DOM 文档(document 格式)
status HTTP状态码(数字形式)
statusText HTTP状态说明(文本格式)

  在接收到响应后,第一步是检查 status 属性,以确定响应已经成功返回。一般来说,可以将 HTTP 状态码为 200 作为响应成功的标志。此时,responseText 属性的内容已经就绪,而且在内容类型正确的情况下,responseXML 也可以访问了。此外,状态码为 304 表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本;当然,也意味着响应是有效的。

  无论内容类型是什么,响应主体的内容都会保存到 responseText 属性中,而对于非 XML 数据而言,responseXML 属性的值将为 null;

  1. if((xhr.status >=200 && xhr.status < 300) || xhr.status == 304){
  2. alert(xhr.responseText);
  3. }else{
  4. alert('请求失败,响应代码为:' + xhr.status);
  5. }

异步响应和同步响应

  如果不设置 open() 方法的第三个参数(默认为true,即异步响应)。

  如果接收的是异步响应,这就需要检测 XMLHttpRequset 对象的 readyState 属性,该属性表示 请求/响应 过程的当前活动阶段。这个属性可取的值如下:

0(UNSENT) 未初始化 还没调用open()
1(OPEND) 启动 已经调用open() ,但还没调用 send()
2(HEADERS_RECEIVED) 发送 己经调用 send() 方法,且接收到头信息。
3(LOADING) 正在接收 已经接收到部分响应主体信息。
4(DONE) 完成 已经接收到全部响应数据,而且已经可以在客户端使用了。

  理论上,只要 readyState 属性值由一个值变成另一个值,都会触发一次 readystatechange 事件。可以利用这个事件来检测每次状态变化后 readyState 的值。通常,我们对readyState 值为4的阶段感兴趣,因为这时所有数据都已就绪。

  必须在调用 open() 之前指定 onreadystatechange 事件处理程序才能确保跨浏览器兼容性,否则将无法接收 readyState 属性为0和1的情况 。

  1. xhr.onreadystatechange = function(){
  2. if(xhr.readyState === 4){
  3. if(xhr.status == 200){
  4. alert(xhr.responseText);
  5. }
  6. }
  7. }

  如果将 open() 方法的第三个参数设置为 false,接收的就是同步响应,那么 send() 方法将阻塞直到请求完成。一旦 send() 返回,仅需要检查 XHR对象的 status 和responseText 属性即可。

  应该避免使用同步请求。客户端 javascript 是单线程的,当 send() 方法阻塞时,它通常会导致整个浏览器 UI 冻结。如果连接的服务器响应慢,那么用户的浏览器将冻结,用户体验非常不好。

进度事件

  一般地,使用 readystatechange 事件探测 HTTP 请求的完成。XHR2 规范草案定义了进度事件 Progress Events 规范,XMLHttpRequest 对象在请求的不同阶段触发不同类型的事件,所以它不再需要检査 readyState 属性。

  有以下6个进度事件:

  1. loadstart: 在接收到响应数据的第一个字节时触发
  2. progress: 在接收响应期间持续不断地触
  3. error: 在请求发生错误时触发
  4. abort: 在因为调用abort()方法而终止连接时触发
  5. load: 在接收到完整的响应数据时触发
  6. loadend: 在通信完成或者触发error、abort或load事件后触发
  7. timeout: 超时发生时触发

  每个请求都从触发 loadstart 事件开始,接下来,通常每隔50毫秒左右触发一次 progress 事件,然后触发 load、error、abort 或 timeout 事件中的一个,最后以触发 loadend 事件结束

  对于任何具体请求,浏览器将只会触发 load、abort、timeout 和 error 事件中的一个。XHR2规范草案指出一旦这些事件中的一个发生后,浏览器应该触发 loadend 事件。

load

  响应接收完毕后将触发 load 事件,因此也就没有必要去检查 readyState 属性了。但一个完成的请求不一定是成功的请求,例如,onload 事件的处理程序应该检查 XMLHttpRequest 对象的 status 状态码来确定收到的是“200 OK”而不是“404 Not Found”的HTTP响应

progress

  progress 事件会在浏览器接收新数据期间周期性地触发。而 onprogress 事件处理程序会接收到一个 event 对象,其 target 属性是 XHR 对象,但包含着三个额外的属性:lengthComputable、loaded 和t otal。其中,lengthComputable 是一个表示进度信息是否可用的布尔值,loaded 表示已经接收的字节数,total 表示根据 Content-Length 响应头部确定的预期字节数。有了这些信息,就可以为用户创建一个进度指示器了。

上传进度upload

  除了为监控 HTTP 响应的加载定义的这些有用的事件外,XHR2 也给出了用于监控 HTTP 请求上传的事件。在实现这些特性的浏览器中,XMLHttpRequest 对象将有 upload 属性。upload 属性值是一个对象,它定义了 addEventListener() 方法和整个 progress 事件集合,比如 onprogress 和 onload。但 upload 对象没有定义 onreadystatechange 属性,upload  仅能触发新的事件类型。

  1. <input type="file" name="file1" id="file1" style="display:none">
  2. <button id="btn">上传文件</button>
  3. <div id="pro"></div>
  4. <div id="result"></div>
  5. <script>
  6. btn.onclick = function(){
  7. file1.click();
  8. pro.innerHTML = result.innerHTML = '';
  9. }
  10. file1.onchange = function(){
  11. //创建xhr对象
  12. var xhr = new XMLHttpRequest();
  13. var data = file1.files[0];
  14. //上传事件
  15. xhr.upload.onprogress = function(e){
  16. e = e || event;
  17. if (e.lengthComputable){
  18. pro.innerHTML = "上传进度为:" + e.loaded + " of " + e.total + " bytes" + ';百分比为:' + e.loaded/e.total;
  19. }
  20. }
  21. xhr.onload = function(e){
  22. var data = xhr.responseText;
  23. e = e || event;
  24. if(xhr.status == 200){
  25. result.innerHTML = data;
  26. }
  27. };
  28. //发送请求
  29. xhr.open('post','pp.php',true);
  30. xhr.setRequestHeader("content-type",data.type);
  31. xhr.send(data);
  32. }
  33. </script>

超时、中止、错误事件

  HTTP 请求无法完成有3种情况。如果请求超时,会触发 timeout 事件。如果请求中止,会触发 abort 事件。最后,像太多重定向这样的网络错误会阻止请求完成,但这些情况发生时会触发 error 事件。

  可以通过调用 XMLHttpRequest 对象的 abort() 方法来取消正在进行的 HTTP 请求。调用 abort() 的主要原因是完成取消或超时请求消耗的时间太长或当响应变得无关时。

  XHR对象的 timeout 属性等于一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。该属性默认等于0,表示没有时间限制。如果请求超时,将触发ontimeout 事件。

  1. <script>
  2. var xhr = new XMLHttpRequest();
  3. btn.onclick = function(){
  4. xhr.abort();
  5. }
  6. xhr.onabort = function(){
  7. console.log("请求已终止");
  8. }
  9.  
  10. xhr.ontimeout = function(){
  11. console.log('请求超时');
  12. }
  13. xhr.timeout = 3000;
  14.  
  15. xhr.onerror = function(){
  16. console.log("请求报错");
  17. }
  18. xhr.onloadend = function(){
  19. console.log("请求结束");
  20. }
  21. </script>

jacascript AJAX 学习的更多相关文章

  1. jacascript Ajax 学习之 JQuery-Ajax

    jQuery 对 ajax 操作进行了封装,在 jQuery 中 $.ajax() 属性最底层的方法,第2层是 load().$.get() 和 $.post() 方法,第3层是 $.getScrip ...

  2. Ajax学习心得

    Ajax学习心得 大致学了下Ajax,才知道它不是某种编程语言,而是一种在无需加载整个页面的情况下能够更新部分网页的技术.了解了它的功能后觉得这真是一种好的技术,这得给前端和运维省多少力啊! 传统的网 ...

  3. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  4. ajax学习之post请求步骤

    ajax学习之post请求步骤 蚣汉御豁 讼护尧 娉郐皑 磲 力豪强的虎视眈眈相信过不了 觏随迦趾 怪了灵敏儿竟然不慌不忙的也没有来找她们 缸轰诎 ?ê戆冼 跄鲅胗绩 掳戈玉孑 馀模嗷婧 ...

  5. AJAX学习前奏----JS基础加强

     AJAX学习前奏----JS基础加强 知识概要: 1.js类&属性&方法的定义 2.静态属性与方法 3.构造方法 4.原型的使用 5.Object对象直接加属性和方法 6.JSO ...

  6. AJAX学习必备三本书

    <AJAX基础教程>AJAX必备图书之一.国内发行的第一本AJAX图书,也是目前最好的AJAX入门书,如果您是AJAX新手,此书是最好的入门图书.本书基本包括了实现Ajax需要了解的大部分 ...

  7. AJAX学习2

    作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正. 本文学习内容:https://www. ...

  8. [学习笔记]AJAX学习

    AJAX学习 ——在w3cschool学习AJAX的学习笔记 参考网站:w3cschool XMLHttpRequest 是 AJAX 的基础. XMLHttpRequest 对象 所有现代浏览器均支 ...

  9. AJAX学习小结

    12345678910 $.ajax({ "url":"", //访问路径 "data":"", // 需要传输的数据 ...

随机推荐

  1. maven项目与普通项目的区别

    maven项目 1:创建方式不同 (web项目举例) 第一种: 第二种: 2:目录结构  稍有不同 3:Pom文件 添加依赖信息,需要那个jar包的时候  加入哪个jar包的依赖,要不然无法使用这个j ...

  2. webpack-dev-server 设置反向代理解决跨域问题

    一.设置代理的原因 现在对前端开发的要求越来越高,并且随着自动化以及模块化的 诞生,前后端开发模式越来越流行.后端只负责接口,前端负责数据展示.逻辑处理.但是前后端开发模式,有一个重要的问题,就是跨域 ...

  3. android中activity.this跟getApplicationContext的区别

    转载: http://www.myexception.cn/android/1968332.html android中activity.this和getApplicationContext的区别 在a ...

  4. 推荐一个利用 python 生成 pptx 分析报告的工具包:reportgen

    reportgen v0.1.8 更新介绍 这段时间,我对 reportgen 进行了大工程量的修改和更新.将之前在各个文章中出现的函数进行了封装,同时也对现有工具包的一些逻辑进行了调整. 1.rep ...

  5. SSH相关知识

    SSH(Secure Shell, 安全Shell协议)是一种加密的网络传输协议,经常用于安全的远程登录. SSH只是一种协议,可以有多种实现. OPENSSH是一种应用广泛的实现. sshd是dae ...

  6. 【Alpha版本】冲刺阶段 - Day3 - 逆风

    今日进展 袁逸灏:右上角两个按键的添加与实现监听(5h) 刘伟康:继续借鉴其他 alpha 冲刺博客,由于我们组的App原型可以在 alpha 阶段完成,所以不需要墨刀工具展示原型(2h) 刘先润:更 ...

  7. alpha-咸鱼冲刺day2

    一,合照 emmmmm.自然是没有的. 二,项目燃尽图 三,项目进展 今天并没有什么进展,弄了好久好像也只研究出怎么把JS的功能块插入进去.html的信息提交这些还不知道要怎么弄. 四,问题困难 日常 ...

  8. 项目Alpha冲刺Day5

    一.会议照片 二.项目进展 1.今日安排 熟悉后台框架并尝试编写及继续搭建前台框架模版.完成登录相关的功能实现,添加一些用户相关的单元测试代码,以及相应的测试数据. 2.问题困难 前端不是很熟,页面框 ...

  9. 团队作业4——第一次项目冲刺(Alpha版本)11.18

    a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: 整理各自的任务汇报: 全分享遇到的困难一起讨论: 讨论接下来的计划: b. 每个人的工作 (有work item 的ID) 1.前两天 ...

  10. 团队作业4——第一次项目冲刺(Alpha版本)2017.11.19

    第三次会议:2017-11-16 第二次会议讨论的还没有完全实现,于是在第三次会议上对此进行了一些对我们工作上的看法,得出结论:多花时间啊!!!! 又没照照片图: 会议主要内容: 1.登录注册完善 2 ...