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

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

创建对象

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

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

        <script type="text/javascript">var xhr;if(window.XMLHttpRequest){xhr = new XMLHttpRequest();}else{xhr = new ActiveXObject('Microsoft.XMLHTTP');}</script>

发送请求

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

open()

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

       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() 方法的参数为要发送的数据。

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

GET

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

  【数据发送】

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

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

  【编码】

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

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

    <script>var url = 'test.php' +'?name=' + encodeURIComponent("你好");xhr.open('GET',url+'&'+Number(new Date()),true);xhr.send(null);</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"请求的两倍。

    <script>xhr.open('POST',url,true);//设置请求头
        xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");//拼接数据var strData = 'name="abc"&num=123';//发送请求
        xhr.send(strData);</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;

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

异步响应和同步响应

  如果不设置 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的情况 。

            xhr.onreadystatechange = function(){if(xhr.readyState === 4){if(xhr.status == 200){alert(xhr.responseText);}}}

  如果将 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  仅能触发新的事件类型。

    <input type="file" name="file1" id="file1" style="display:none"><button id="btn">上传文件</button><div id="pro"></div><div id="result"></div><script>btn.onclick = function(){file1.click();pro.innerHTML = result.innerHTML = ''; } file1.onchange = function(){ //创建xhr对象 var xhr = new XMLHttpRequest(); var data = file1.files[0]; //上传事件  xhr.upload.onprogress = function(e){ e = e || event; if (e.lengthComputable){ pro.innerHTML = "上传进度为:" + e.loaded + " of " + e.total + " bytes" + ';百分比为:' + e.loaded/e.total;  } } xhr.onload = function(e){ var data = xhr.responseText; e = e || event; if(xhr.status == 200){ result.innerHTML = data; } }; //发送请求  xhr.open('post','pp.php',true); xhr.setRequestHeader("content-type",data.type); xhr.send(data); } </script>

超时、中止、错误事件

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

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

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

    <script>var xhr = new XMLHttpRequest();btn.onclick = function(){xhr.abort();}xhr.onabort = function(){ console.log("请求已终止"); } xhr.ontimeout = function(){ console.log('请求超时'); } xhr.timeout = 3000; xhr.onerror = function(){ console.log("请求报错"); } xhr.onloadend = function(){ console.log("请求结束"); } </script>

转载于:https://www.cnblogs.com/sspeng/p/7648620.html

jacascript AJAX 学习相关推荐

  1. asp.net的Ajax学习进阶

    asp.net的Ajax学习进阶 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/           时间:2007.6.3  1.什么是Ajax? 2006年忽如 ...

  2. ajax请求返回json实例,Jquery Ajax 学习实例2 向页面发出请求 返回JSon格式数据

    一.AjaxJson.aspx 处理业务数据,产生JSon数据,供JqueryRequest.aspx调用,代码如下: protected void Page_Load(object sender, ...

  3. ajax post 没有返回_Ajax异步技术之三:jQuery中的ajax学习

    jQuery中的Ajax学习: jQuery是js的一个轻量型框架,已经将js创建的操作进行了封装,而ajax也是js的一部分,所以jQuery也已经将ajax进行了封装. 封装: $.get(url ...

  4. 我的AJAX 学习系列文章

    我最近学习AJAX 的笔记 AJAX 学习笔记[一] 简单的异步通信示例 AJAX 学习笔记[二] 我编写的AJAX 测试代码示例 AJAX 学习笔记[三] get 与post 模式的区别 AJAX ...

  5. Ajax学习日志(三)—— 如何传递get请求参数

    Ajax入门(三) 一.如何传递get请求参数 1.1) 在app.js创建新路由 1.2) 在public文件夹新建一个html文件 1.3)运行 一.如何传递get请求参数 1.1) 在app.j ...

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

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

  7. Ajax 学习 二 Accordion和AccordionPane 淡入淡出效果和AutoSize自动尺寸

    Ajax 学习 二 Accordion和AccordionPane 淡入淡出效果和AutoSize自动尺寸 源代码 View Code <%@ Page Language="C#&qu ...

  8. ajax 学习第四天

    ajax 学习第四天 文章目录 ajax 学习第四天 1. 同源策略 1.1 同源 1.2 同源策略 2. 跨域 2.1 跨域拦截 2.2 实现跨域数据请求 3. JSONP 3.1 JSONP 实现 ...

  9. ajax学习记录总结

    Ajax学习记录 URL 地址组成:客户端与服务器之间的通信协议 存有该资源的服务器名称 资源在服务器上具体的存放位置 客户端与服务器通信过程 请求-处理-相应 资源的请求方式 get请求用于获取服务 ...

最新文章

  1. DockOne微信分享(一一二):Flannel中vxlan backend的原理和实现
  2. 大巧不工-WEB前端设计修炼之道pdf
  3. Java知识点总结(Java容器-EnumSet)
  4. python判断点在矩形内_Python测试点是否在矩形中
  5. Python按键精灵自动化_安装Python
  6. jquery radiobutton使用
  7. 性能调优必备利器之 JMH
  8. 云在天之南——我的七天七夜(率性苍山洱海)
  9. 为什么日本人晚上那么晚去居酒屋吃炸鸡喝啤酒,但街上却鲜有胖子?
  10. rm如何在Linux中删除一个大文件
  11. 【转】HTTP响应报文与工作原理详解
  12. ajax给表格填值,填报表用ajax实现关联单元格自动填充
  13. Atitit r2017 r5 doc list on home ntpc.docx 驱动器 D 中的卷是 p2soft 卷的序列号是 9AD0-D3C8 D:\ati\r2017 v4 r
  14. JAVAEE智慧树第二次作业
  15. C#路径中使用斜杠/和反斜杠\的区别
  16. Python学习模块 Pygame写游戏二(太空大战)
  17. MySQL基本命令操作
  18. Qtum量子链QIP-5提案:在智能合约交易输出脚本上增加签名证明,允许用户以代付方式调用合约
  19. 使用Html.fromHtml()怎么加载Html中的图片
  20. spring JDBCTemplate实现批量插入及返回id

热门文章

  1. cesium 页面截图_Cesium开发入门篇 | 02开发环境搭建及第一个示例
  2. linux命令deploy_Linux deploy 使用教程
  3. opencv 二值化_Python-OpenCV获取图像轮廓的图像处理方法
  4. Spring.io本地服务器解决超时问题
  5. Django 模板实现(动态)图片/头像展示到页面
  6. .net与mysql,ASP.NET与MySql的连接
  7. 二、mongodb数据库系列——聚合操作 索引操作 权限管理
  8. ACwing 3. 完全背包问题(DP)
  9. LeetCode 369. 给单链表加一(递归)
  10. LeetCode 853. 车队(排序)