• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

XMLHttpRequest对象 AjAX的使用

武飞扬头像
菜鸟-忆楦(没进阶前不改)
帮助1

目录

XHR(XMLHttpRequest)的历史:

使用XHR(XMLHttpRequest)

        open() 方法                             ------                      定义请求

        send() 方法                             ------                      发送请求

        responseText                         ------                       作为响应体返回的文本

        responseXML                        ------                       作为响应体返回的XML DOM 文档

        status                                     ------                        响应的HTTP状态

        statusText                              ------                        响应的HTTP状态描述

                               

         readyState                             ------                        表示当前处在请求/响应过程的哪个阶段。

        onreadystatechange                ------                        检测readySate值变化的事件

        abort()                                        ------                      取消异步请求

HTTP头部

        

        setRequestHeader()                        ------               发送额外的请求头部

        

        getResponseHeader()                        ------                获取响应头部(指定头部名称的值)

        getAllResponseHeader()                    ------                获取所有的响应头部              

GET请求

POST请求

XMLHttpRequest Level 2

        FormData 类型

                append()                                        ------                    给FormData对象添加任意多个键/值对数据

                直接给FormData构造函数传入一个表单元素,也可以将表单中的数据作为键/值对填充进去

        timeou                                        ------                        超时属性 

        overrideMimeType()                      ------            重写XHR响应的MIME类型

进度事件

        load事件

        progress事件


XHR(XMLHttpRequest)的历史:

IE5是第一个引入XHR对象的浏览器。这个对象是通过ActiveX对象实现并包含在MSXML库中的。为此,XHR对象的3个版本在浏览器中分别被暴露为MSXML2.XMLHttp、MSXML2.XMLHttp.3.0和MXSML2.XMLHttp.6.0。

AJAX出现之前 JS 对服务器的请求方式是通过 Java小程序 或 Fetch影片 来发请求的

AJAX技术是一种远程脚本

使用XHR(XMLHttpRequest)

        open() 方法                             ------                      定义请求

                使用XHR对象第一步先要调用open()方法

                语法:xhr.open("get","url",false)

                参数:

                        method 第一个参数: get、post等等

                        url 第二个参数: 发起请求的URL 也就是服务器的 协议、域名、端口

                        false 第三个参数: false同步模式   true异步模式

                注意:发起请求的URL必须与当前页面是 协议、域名、端口 都一样的,不然会报跨域错误

        send() 方法                             ------                      发送请求

                send()方法接收一个参数,是作为请求体发送的数据。如果不需要发送请求体,则必须传null,因为这个参数在某些浏览器中是必需的。调用send()之后,请求就会发送到服务器。

                因为这个请求是同步的,所以JavaScript代码会等待服务器响应之后再继续执行。收到响应后,XHR对象的以下属性会被填充上数据。

                语法:xhr.send(null)

                参数:

                        如果服务器需要接收指定参数,那就是放在send(item)里面

                注意:如果不需要发送请求体,则必须传null,因为这个参数在某些浏览器中是必需的。

        responseText                         ------                       作为响应体返回的文本

        responseXML                        ------                       作为响应体返回的XML DOM 文档

        status                                     ------                        响应的HTTP状态

                收到响应后,第一步要检查status属性以确保响应成功返回。

                 HTTP状态码为2xx表示成功。responseText或responseXML内容类型正确属性中就会有内容。               

                如果HTTP状态码是304,则表示资源未修改过,是从浏览器缓存中直接拿取的。当然这也意味着响应有效。

        

  1.  
    // 创建一个XHR(XMLHttpRequest)对象
  2.  
    let xhr = new XMLHttpRequest()
  3.  
     
  4.  
    // 定义请求
  5.  
    xhr.open("get","url",false)
  6.  
     
  7.  
    // 发送请求
  8.  
    xhr.send(null)
  9.  
     
  10.  
    // 根据status响应回来的状态来判断是否接收到响应数据
  11.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  12.  
    alert(xhr.responseText)
  13.  
    } else {
  14.  
    alert("请求失败,响应回来状态码是:" xhr.status)
  15.  
    }

                注意:

                        最好检查status而不是statusText属性,因为后者已经被证明在跨浏览器的情况下不可靠。

                        无论是什么响应内容类型,responseText属性始终会保存响应体,而responseXML则对于非XML数据是null。

        statusText                              ------                        响应的HTTP状态描述

                               

         readyState                             ------                        表示当前处在请求/响应过程的哪个阶段。

0 未初始化(Uninitialized)。尚未调用open()方法。
1 已打开(Open)。已调用open()方法,尚未调用send()方法。
2 已发送(Sent)。已调用send()方法,尚未收到响应。
3 接收中(Receiving)。已经收到部分响应。
4 完成(Complete)。已经收到所有响应,可以使用了。

                每次readyState从一个值变成另一个值,都会触发readystatechange事件。可以借此机会检查readyState的值。

        onreadystatechange                ------                        检测readySate值变化的事件

                onreadystatechange事件处理程序应该在调用open()之前赋值。

  1.  
    // 使用的是DOM Level 0 的风格为XHR对象添加了事件处理程序
  2.  
     
  3.  
    // 创建一个 XHR(XMLHttpRequest) 对象
  4.  
    let xhr = new XMLHttpRequest()
  5.  
     
  6.  
    // 因为是个异步请求所以可以使用 onreadystatechange 事件
  7.  
    // 使用onreadystatechange事件 检测readyState的值 来显示 responseText响应回来的数据
  8.  
    xhr.onreadystatechange = function() {
  9.  
    // 判断readyState的值是否是4 是否处理完了
  10.  
    if (xhr.readyState == 4) {
  11.  
     
  12.  
    // 判断响应回来的status状态码
  13.  
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  14.  
     
  15.  
    alert(xhr.responseText)
  16.  
    } else {
  17.  
     
  18.  
    alert("请求失败,响应回来的状态码是:" xhr.status)
  19.  
    }
  20.  
     
  21.  
    }
  22.  
    }
  23.  
     
  24.  
    // 定义请求
  25.  
    xhr.open("get", "url", true)
  26.  
     
  27.  
    // 发送请求
  28.  
    xhr.send(null)

                以上代码使用DOM Level 0风格为XHR对象添加了事件处理程序,因为并不是所有浏览器都支持DOM Level 2风格。与其他事件处理程序不同,onreadystatechange事件处理程序不会收到event对象。在事件处理程序中,必须使用XHR对象本身来确定接下来该做什么。

                注意:由于onreadystatechange事件处理程序的作用域问题,这个例子在onreadystatechange事件处理程序中使用了xhr对象而不是this对象。使用this可能导致功能失败或导致错误,取决于用户使用的是什么浏览器。因此还是使用保存XHR对象的变量更保险一些。

        abort()                                        ------                      取消异步请求

                调用这个方法后,XHR对象会停止触发事件,并阻止访问这个对象上任何与响应相关的属性。中断请求后,应该取消对XHR对象的引用。由于内存问题,不推荐重用XHR对象。

HTTP头部

        每个HTTP请求和响应都会携带一些头部字段,这些字段可能对开发者有用。XHR对象会通过一些方法暴露与请求和响应相关的头部字段。

        默认情况下,XHR请求会发送以下头部字段。

        

Accept: 浏览器可以处理的内容类型。
Accept-Charset: 浏览器可以显示的字符集。
Accept-Encoding: 浏览器可以处理的压缩编码类型。
Accept-Language: 浏览器使用的语言。
Connection: 浏览器与服务器的连接类型。
Cookie: 页面中设置的Cookie。
Host: 发送请求的页面所在的域。
Referer: 发送请求的页面的URI。注意,这个字段在HTTP规范中就拼错了,所以考虑到兼容性也必须将错就错。(正确的拼写应该是Referrer。)
User-Agent: 浏览器的用户代理字符串。

        setRequestHeader()                        ------               发送额外的请求头部

                虽然不同浏览器发送的确切头部字段可能各不相同,但这些通常都是会发送的。如果需要发送额外的请求头部,可以使用setRequestHeader()方法。这个方法接收两个参数:头部字段的名称和值。

                注意:为保证请求头部被发送,必须在open()之后、send()之前调用setRequestHeader()

  1.  
    // 创建一个XHR(XMLHttpRequest)对象
  2.  
    let xhr = new XMLHttpRequest()
  3.  
     
  4.  
    // 判断响应是否处理完了
  5.  
    xhr.onreadystatechange = function(){
  6.  
    // 判断readyState是否等于4
  7.  
    if(xhr.readyState == 4) {
  8.  
    // 判断status状态码是否等于或大于200小于300 或 等于304
  9.  
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
  10.  
    alert(xhr.responseText)
  11.  
    } else {
  12.  
    alert("请求失败,响应回来的状态码是:" xhr.status)
  13.  
    }
  14.  
    }
  15.  
    }
  16.  
     
  17.  
    // 定义请求
  18.  
    xhr.open("get", "url", true)
  19.  
     
  20.  
    // 额外定义一个请求头
  21.  
    xhr.setRequestHeader("MyHeader", "MyValue")
  22.  
     
  23.  
    // 发送请求
  24.  
    xhr.send(null)

                虽然不同浏览器发送的确切头部字段可能各不相同,但这些通常都是会发送的。如果需要发送额外的请求头部,可以使用setRequestHeader()方法。这个方法接收两个参数:头部字段的名称和值。为保证请求头部被发送,必须在open()之后、send()之前调用setRequestHeader()

        

        getResponseHeader()                        ------                获取响应头部(指定头部名称的值)

                只有一个参数

                只要传入要获取头部的名称即可。

        getAllResponseHeader()                    ------                获取所有的响应头部              

                服务器可以使用头部向浏览器传递额外的结构化数据。

                getAllResponseHeaders()方法通常返回类似如下的字符串:

                        Date: Sun, 14 Nov 2004 18:04:03 GMT

                        Server: Apache/1.3.29 (Unix)

                        Vary: Accept

                        X-Powered-By: PHP/4.3.8

                        Connection: closeContent-Type: text/html; charset=iso-8859-1

                通过解析以上头部字段的输出,就可以知道服务器发送的所有头部,而不需要单独去检查了。 

GET请求

        最常用的请求方法是GET请求,用于向服务器查询某些信息。必要时,需要在GET请求的URL后面添加查询字符串参数。对XHR而言,查询字符串必须正确编码后添加到URL后面,然后再传给open()方法。

        发送GET请求最常见的一个错误查询字符串格式不对。查询字符串中的每个名和值都必须使用encodeURIComponent()编码,所有名/值对必须以和号(&)分隔

        实例:

  1.  
    // 这里使用addURLParam()函数可以保证通过XHR发送请求的URL格式正确。
  2.  
     
  3.  
    // 创建一个XHR(XMLHttpRequest)对象
  4.  
    let xhr = new XMLHttpRequest()
  5.  
     
  6.  
    // 定义一个拼接并编码url的方法 addURLParam方法 Param的单词:参数 add的单词:添加
  7.  
    function addURLParam(url, name, value) {
  8.  
    // 先判断url是否有查询开始的? 如果有就代表已经传过值 拼接一个&符号
  9.  
    url = (url.indexOf("?") == -1 ? "?" : "&")
  10.  
     
  11.  
    // encodeURIComponent() 把字符串 替换成 十六进制的转义序列
  12.  
    // 编码name 与 value的值 并拼接到url上
  13.  
    url = encodeURIComponent(name) "=" encodeURIComponent(value)
  14.  
     
  15.  
    // 返回编码并拼接好的url
  16.  
    return url
  17.  
    }
  18.  
     
  19.  
    // 创建一个url的基地址 也就是协议、域名、端口 下面以https://mp.csdn.net 为例
  20.  
    let url = "https://mp.csdn.net"
  21.  
     
  22.  
    // 添加参数
  23.  
    url = addURIParam(url, "name", "Nicholas")
  24.  
     
  25.  
    // 初始化请求
  26.  
    xhr.open("get", url, false)
  27.  
     
  28.  
    // 发送请求
  29.  
    xhr.send(null)

POST请求

        用于向服务器发送应该保存的数据。每个POST请求都应该在请求体中携带提交的数据,而GET请求则不然。POST请求的请求体可以包含非常多的数据,而且数据可以是任意格式。要初始化POST请求,open()方法的第一个参数要传"post"
        send()方法传入要发送的数据。因为XHR最初主要设计用于发送XML,所以可以传入序列化之后的XML DOM文档作为请求体。当然,也可以传入任意字符串。

        默认情况下,对服务器而言,POST请求与提交表单是不一样的。服务器逻辑需要读取原始POST数据才能取得浏览器发送的数据。不过,可以使用XHR模拟表单提交。为此,第一步需要把Content-Type头部设置为"application/x-www-formurlencoded",这是提交表单时使用的内容类型。第二步是创建对应格式的字符串。POST数据此时使用与查询字符串相同的格式。如果网页中确实有一个表单需要序列化并通过XHR发送到服务器,则可以使用serialize()函数来创建相应的字符串。

  1.  
    function submitData() {
  2.  
    // 创建一个XHR(XMLHttpRequest)对象
  3.  
    let xhr = new XMLHttpRequest()
  4.  
     
  5.  
    // 判断响应是否处理完了
  6.  
    xhr.onreadystatechange = function() {
  7.  
     
  8.  
    // 判断readyState是否等于4
  9.  
    if (xhr.readyState == 4) {
  10.  
     
  11.  
    // 判断status状态码是否等于或大于200小于300 或 等于304
  12.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  13.  
    alert(xhr.responseText)
  14.  
    } else {
  15.  
    alert("请求失败,响应回来的状态码是:" xhr.status)
  16.  
    }
  17.  
    }
  18.  
    }
  19.  
     
  20.  
    // 初始化请求
  21.  
    xhr.open("post", "postexample.php", true)
  22.  
     
  23.  
    // 设置请求头
  24.  
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
  25.  
     
  26.  
    // 获取表单标签
  27.  
    let form = document.getElementById("user-info")
  28.  
     
  29.  
    // 发送 用serialize() 将表单内容序列化成一个字符串。
  30.  
    xhr.send(serialize(form));
  31.  
     
  32.  
    }

                注意:POST请求相比GET请求要占用更多资源。从性能方面说,发送相同数量的数据,GET请求比POST请求要快两倍。

XMLHttpRequest Level 2

        XHR对象作为事实标准的迅速流行,也促使W3C为规范这一行为而制定了正式标准。XMLHttpRequest Level 1只是把已经存在的XHR对象的实现细节明确了一下。XMLHttpRequest Level 2又进一步发展了XHR对象。并非所有浏览器都实现了XMLHttpRequest Level 2的所有部分,但所有浏览器都实现了其中部分功能。

        FormData 类型

                现代Web应用程序中经常需要对表单数据进行序列化,因此XMLHttpRequest Level 2新增了FormData类型。FormData类型便于表单序列化,也便于创建与表单类似格式的数据然后通过XHR发送。下面的代码创建了一个FormData对象,并填充了一些数据:

                append()                                        ------                    给FormData对象添加任意多个键/值对数据

  1.  
    let data = new FormData()
  2.  
     
  3.  
    data.append("name", "Nicholas")

                直接给FormData构造函数传入一个表单元素,也可以将表单中的数据作为键/值对填充进去

let data = new FormData(document.forms[0])

                实例:                        

  1.  
    // 创建一个XHR(XMLHttpRequest)对象
  2.  
    let xhr = new XMLHttpRequest()
  3.  
     
  4.  
    // 判断响应是否处理完了
  5.  
    xhr.onreadystatechange = function() {
  6.  
     
  7.  
    // 判断readyState是否等于4
  8.  
    if (xhr.readyState == 4) {
  9.  
     
  10.  
    // 判断status状态码是否等于或大于200小于300 或 等于304
  11.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  12.  
    alert(xhr.responseText)
  13.  
    } else {
  14.  
    alert("请求失败,响应回来的状态码是:" xhr.status)
  15.  
    }
  16.  
     
  17.  
    }
  18.  
     
  19.  
    }
  20.  
     
  21.  
    // 初始化请求
  22.  
    xhr.open("post", "url", true)
  23.  
     
  24.  
    // 获取表单标签
  25.  
    let form = document.getElementById("user-info")
  26.  
     
  27.  
    // 使用FormDate对象序列化form表单
  28.  
    xhr.send(new FormData(form))

                        使用FormData的另一个方便之处是不再需要给XHR对象显式设置任何请求头部了。XHR对象能够识别作为FormData实例传入的数据类型并自动配置相应的头部。

        timeou                                        ------                        超时属性 

                IE8给XHR对象增加了一个timeout属性,用于表示发送请求后等待多少毫秒,如果响应不成功就中断请求。之后所有浏览器都在自己的XHR实现中增加了这个属性。在给timeout属性设置了一个时间且在该时间过后没有收到响应时,XHR对象就会触发timeout事件,调用ontimeout事件处理程序。这个特性后来也被添加到了XMLHttpRequest Level 2规范。

  1.  
    let xhr = new XMLHttpRequest()
  2.  
     
  3.  
    xhr.onreadystatechange = function() {
  4.  
    if (xhr.readyState == 4) {
  5.  
    try {
  6.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  7.  
    alert(xhr.responseText)
  8.  
    } else {
  9.  
    alert(" 请求失败,响应回来的状态码是: " xhr.status)
  10.  
    }
  11.  
    } catch (ex) {
  12.  
    //假设由ontimeout处理
  13.  
    }
  14.  
    }
  15.  
    }
  16.  
     
  17.  
    xhr.open("get", "url", true)
  18.  
     
  19.  
    xhr.timeout = 1000; // 设置1秒超时
  20.  
     
  21.  
    xhr.ontimeout = function() {
  22.  
    alert("请求之后响应时间超过了指定的时间");
  23.  
    }
  24.  
     
  25.  
    xhr.send(null)

                这个例子演示了使用timeout设置超时。给timeout设置1000毫秒意味着,如果请求没有在1秒钟内返回则会中断。此时则会触发ontimeout事件处理程序,readyState仍然会变成4,因此也会调用onreadystatechange事件处理程序。不过,如果在超时之后访问status属性则会发生错误。为做好防护,可以把检查status属性的代码封装在try/catch语句中。

        overrideMimeType()                      ------            重写XHR响应的MIME类型

                Firefox首先引入了overrideMimeType()方法用于重写XHR响应的MIME类型。这个特性后来也被添加到了XMLHttpRequest Level 2。因为响应返回的MIME类型决定了XHR对象如何处理响应,所以如果有办法覆盖服务器返回的类型,那么是有帮助的。

                假设服务器实际发送了XML数据,但响应头设置的MIME类型是text/plain。结果就会导致虽然数据是XML,但responseXML属性值是null。此时调用overrideMimeType()可以保证将响应当成XML而不是纯文本来处理

  1.  
    /* 这个例子强制让XHR把响应当成XML而不是纯文本来处理。
  2.  
    为了正确覆盖响应的MIME类型,必须在调用send()之前调用overrideMimeType()。
  3.  
    */
  4.  
     
  5.  
    let xhr = new XMLHttpRequest()
  6.  
     
  7.  
    xhr.open("get", "url", true)
  8.  
     
  9.  
    xhr.overrideMimeType("text/xml")
  10.  
     
  11.  
    xhr.send(null)

                注意:必须在调用send()之前调用overrideMimeType()

进度事件

        Progress Events是W3C的工作草案,定义了客户端-服务器端通信。这些事件最初只针对XHR,现在也推广到了其他类似的API。有以下6个进度相关的事件。

loadstart: 在接收到响应的第一个字节时触发。
progress: 在接收响应期间反复触发。
error: 在请求出错时触发。
abort: 在调用abort()终止连接时触发。
load: 在成功接收完响应时触发。
loadend: 在通信完成时,且在error、abort或load之后触发。

        每次请求都会首先触发loadstart事件,之后是一个或多个progress事件,接着是error、abort或load中的一个,最后以loadend事件结束。

        load事件

                Firefox最初在实现XHR的时候,曾致力于简化交互模式。最终,增加了一个load事件用于替代readystatechange事件。load事件在响应接收完成后立即触发,这样就不用检查readyState属性了。onload事件处理程序会收到一个event对象,其target属性设置为XHR实例,在这个实例上可以访问所有XHR对象属性和方法。不过,并不是所有浏览器都实现了这个事件的event对象。考虑到跨浏览器兼容,还是需要像下面这样使用XHR对象变量

  1.  
    let xhr = new XMLHttpRequest()
  2.  
     
  3.  
    xhr.onload = function() {
  4.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  5.  
    alert(xhr.responseText)
  6.  
    } else {
  7.  
    alert("请求失败,响应回来的状态码是: " xhr.status);
  8.  
    }
  9.  
    }
  10.  
     
  11.  
    xhr.open("get", "url", true)
  12.  
     
  13.  
    xhr.send(null)

                只要是从服务器收到响应,无论状态码是什么,都会触发load事件。这意味着还需要检查status属性才能确定数据是否有效。Firefox、Opera、Chrome和Safari都支持load事件。

        progress事件

                Mozilla在XHR对象上另一个创新是progress事件,在浏览器接收数据期间,这个事件会反复触发。每次触发时,onprogress事件处理程序都会收到event对象,其target属性是XHR对象,且包含3个额外属性:lengthComputableposition和totalSize。其中,lengthComputable是一个布尔值,表示进度信息是否可用;position是接收到的字节数;totalSize是响应的Content-Length头部定义的总字节数。有了这些信息,就可以给用户提供进度条了。

  1.  
    let xhr = new XMLHttpRequest()
  2.  
     
  3.  
    xhr.onload = function(event) {
  4.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
  5.  
    alert(xhr.responseText)
  6.  
    } else {
  7.  
    alert("请求失败,响应回来的状态码是: " xhr.status)
  8.  
    }
  9.  
    }
  10.  
     
  11.  
    // 每次触发progress事件都会更新HTML元素中的信息。假设响应有Content-Length头部,就可以利用这些信息计算出已经收到响应的百分比。
  12.  
    xhr.onprogress = function(event) {
  13.  
    let divStatus = document.getElementById("status")
  14.  
    if (event.lengthComputable) {
  15.  
    divStatus.innerHTML = "Received " event.position " of " event.totalSize "bytes"
  16.  
    }
  17.  
    }
  18.  
     
  19.  
    xhr.open("get", "url", true)
  20.  
     
  21.  
    xhr.send(null)

         注意:为了保证正确执行,必须在调用open()之前添加onprogress事件处理程序。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgchkbf
系列文章
更多 icon
同类精品
更多 icon
继续加载