本文介绍: XHR(XMLHttpRequest)的使用

目录

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 第一个参数: getpost等等

                        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,则表示资源修改过,是从浏览器缓存中直接拿取的。当然这也意味着响应有效。

        

// 创建一个XHR(XMLHttpRequest)对象
let xhr = new XMLHttpRequest()

// 定义请求
xhr.open("get","url",false)

// 发送请求
xhr.send(null)

// 根据status响应回来的状态判断是否收到响应数据
if ((xhr.status &gt;= 200 &amp;&amp; xhr.status < 300) || xhr.status == 304) {
    alert(xhr.responseText)
} else {
    alert("请求失败,响应回来状态码是:" + xhr.status)
}

                注意:

                        最好检查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()之前赋值

// 使用的是DOM Level 0 的风格为XHR对象添加事件处理程序

// 创建一个 XHR(XMLHttpRequest) 对象
let xhr = new XMLHttpRequest()

// 因为是个异步请求所以可以使用 onreadystatechange 事件
// 使用onreadystatechange事件 检测readyState的值 来显示 responseText响应回来的数据
xhr.onreadystatechange = function() {
    // 判断readyState的值是否是4 是否处理完了
    if (xhr.readyState == 4) {

        // 判断响应回来的status状态码
        if((xhr.status &gt;= 200 &amp;&amp; xhr.status < 300) || xhr.status == 304) {

            alert(xhr.responseText)
        } else {

            alert("请求失败,响应回来的状态码是:" + xhr.status)
        }

    }
}

// 定义请求
xhr.open("get", "url", true)

// 发送请求
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()

// 创建一个XHR(XMLHttpRequest)对象
let xhr = new XMLHttpRequest()

// 判断响应是否处理完了
xhr.onreadystatechange = function(){
    // 判断readyState是否等于4
    if(xhr.readyState == 4) {
        // 判断status状态码是否等于或大于200小于300 或 等于304
        if((xhr.status >= 200 &amp;&amp; xhr.status < 300) || xhr.status == 304){
            alert(xhr.responseText)
        } else {
            alert("请求失败,响应回来的状态码是:" + xhr.status)
        }
    }
}

// 定义请求
xhr.open("get", "url", true)

// ++ 额外定义一个请求头
xhr.setRequestHeader("MyHeader", "MyValue")

// 发送请求
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()编码,所有名/值对必须以和号(&amp;)分隔

        实例

// 这里使用addURLParam()函数可以保证通过XHR发送请求的URL格式正确。

// 创建一个XHR(XMLHttpRequest)对象
let xhr = new XMLHttpRequest()

// 定义一个拼接编码url的方法 addURLParam方法  Param单词:参数  add单词:添加
function addURLParam(url, name, value) {
    // 先判断url是否查询开始的? 如果有就代表已经传过值 拼接一个&amp;符号
    url += (url.indexOf("?") == -1 ? "?" : "&amp;")

    // encodeURIComponent() 把字符替换十六进制的转义序列
    // 编码namevalue的值 并拼接到url上
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value)
    
    // 返回编码并拼接好的url
    return url   
}

// 创建一个url的基地址  也就是协议域名端口 下面以https://mp.csdn.net 为例
let url = "https://mp.csdn.net"

// 添加参数
url = addURIParam(url, "name", "Nicholas")

// 初始化请求
xhr.open("get", url, false)

// 发送请求
xhr.send(null)

POST请求

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

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

function submitData() {
    // 创建一个XHR(XMLHttpRequest)对象
    let xhr = new XMLHttpRequest()
    
    // 判断响应是否处理完了
    xhr.onreadystatechange = function() {

        // 判断readyState是否等于4
        if (xhr.readyState == 4) {
            
            // 判断status状态码是否等于或大于200小于300 或 等于304
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                alert(xhr.responseText)
            } else {
                alert("请求失败,响应回来的状态码是:" + xhr.status)
            }
        }
    }
    
    // 初始化请求
    xhr.open("post", "postexample.php", true)

    // 设置请求头
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")

    // 获取表单标签
    let form = document.getElementById("user-info")

    // 发送 用serialize() 将表单内容序列化成一个字符串。
    xhr.send(serialize(form));

}

                注意: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对象添加任意多个键/值对数据

let data = new FormData()

data.append("name", "Nicholas")

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

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

                实例                        

// 创建一个XHR(XMLHttpRequest)对象
let xhr = new XMLHttpRequest()

// 判断响应是否处理完了
xhr.onreadystatechange = function() {

    // 判断readyState是否等于4
    if (xhr.readyState == 4) {

        // 判断status状态码是否等于或大于200小于300 或 等于304
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            alert(xhr.responseText)
        } else {
            alert("请求失败,响应回来的状态码是:" + xhr.status)
        }

    }

}

// 初始化请求
xhr.open("post", "url", true)

// 获取表单标签
let form = document.getElementById("user-info")

// 使用FormDate对象序列化form表单
xhr.send(new FormData(form))

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

        timeou                                        ——                        超时属性 

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

let xhr = new XMLHttpRequest()

xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        try {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                alert(xhr.responseText)
            } else { 
                alert(" 请求失败,响应回来的状态码是: " + xhr.status)
            }
        } catch (ex) { 
            //假设由ontimeout处理
        }
    }
}

xhr.open("get", "url", true)

xhr.timeout = 1000; // 设置1秒超时

xhr.ontimeout = function() {
    alert("请求之后响应时间超过了指定时间");
}

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而不是纯文本处理

/* 这个例子强制让XHR把响应当成XML而不是纯文本处理。
为了正确覆盖响应的MIME类型,必须在调用send()之前调用overrideMimeType()。
*/

let xhr = new XMLHttpRequest()

xhr.open("get", "url", true)

xhr.overrideMimeType("text/xml")

xhr.send(null)

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

进度事件

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

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

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

        load事件

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

let xhr = new XMLHttpRequest()

xhr.onload = function() {
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        alert(xhr.responseText)
    } else {
        alert("请求失败,响应回来的状态码是: " + xhr.status);
    }
}

xhr.open("get", "url", true)

xhr.send(null)

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

        progress事件

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

let xhr = new XMLHttpRequest()

xhr.onload = function(event) {
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        alert(xhr.responseText)
    } else {
        alert("请求失败,响应回来的状态码是: " + xhr.status)
    }
}

// 每次触发progress事件都会更新HTML元素中的信息假设响应有Content-Length头部,就可以利用这些信息计算出已经收到响应的百分比。
xhr.onprogress = function(event) {
    let divStatus = document.getElementById("status")
    if (event.lengthComputable) {
        divStatus.innerHTML = "Received " + event.position + " of " + event.totalSize + "bytes"
    }
}

xhr.open("get", "url", true)

xhr.send(null)

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

原文地址:https://blog.csdn.net/sinat_55275851/article/details/126870505

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_26516.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注