那些年,被 AJAX 折磨的前端小白


在刚开始学 JavaScript 时,最深恶痛绝的三个 JS怪👹:this妖原型精AJAX魔

最近在写总结回顾时竟意外发现这三大怪早已在不知不觉中被我消化吸收了,趁着热乎记下来✍~~~

有请今天的出场嘉宾🎤:AJAX魔

什么是 AJAX

AJAX 是一种用于创建快速动态网页的技术,它使用 XMLHttpRequest 对象与服务器通信。 它可以使用JSON,XML,HTML和text文本等格式发送和接收数据。AJAX最吸引人的就是它的“异步”特性,它可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。

什么是异步

不等任务执行完,直接执行下一个任务

举个例子 🌰

周末我和闺蜜去逛gai,我们打算去吃海底捞,排队的人很多,于是我们手机扫码排号,然后继续逛gai,过一会收到叫号通知就可以进去吃火锅啦~

「排号」这件事并没有立即得到结果(进去吃火锅),所以这是一个异步任务

AJAX 请求数据流程与此类似。

浏览器通过 XMLHttpRequest 对象向服务器发出HTTP请求与接收HTTP响应,浏览器接着做其他事情,等收到 XMLHttpRequest 对象返回来的数据再渲染页面。

AJAX 的使用

1. 创建Ajax核心对象XMLHttpRequest

var httpRequest = null; 
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
    httpRequest = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE 6 and older
    httpRequest = new ActiveXObject("Microsoft.XMLHTTP")
}

2. 发送HTTP请求

httpRequest.open(method, url, async)
httpRequest.send()

method:HTTP请求方法 - 有GET,POST,HEAD以及服务器支持的其他方法

url:文件在服务器上的位置。由于安全原因,默认不能调用第三方URL域名

async:用于设置请求true(异步)或 false(同步)

send() 方法的参数可以是任何你想发送给服务器的内容。

如果是 POST 请求的话,需注意:

  • 在调用 send() 方法获取表单数据前要设置请求头的格式内容
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
  • 发送表单数据时应该用服务器可以解析的格式,像查询语句,JSON,XML等
// 举例
httpRequest.send("name=xcl&anothername=April")  

3. 处理服务器响应

有关的 API :

  • XMLHttpRequest.onreadystatechange:只要 readyState 属性发生变化,就会调用相应的处理函数

  • XMLHttpRequest.response:返回响应的正文,返回的类型取决于 responseType 属性

  • XMLHttpRequest.responseText:服务器以文本字符的形式返回

  • XMLHttpRequest.responseXML:以 XMLDocument 对象方式返回,之后就可以使用JavaScript来处理

  • XMLHttpRequest.readyState:返回一个 XMLHttpRequest 代理当前所处的状态(请求的状态码),它的值含义:

    • 0 未初始化 – 尚未调用.open()方法

    • 1 启动 – 已经调用.open()方法,但尚未调用.send()方法

    • 2 发送 – 已经调用.send()方法,但尚未接收到响应

    • 3 接收 – 已经接收到部分响应数据

    • 4 完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了

  • XMLHttpRequest.status:返回了 XMLHttpRequest 响应中的数字状态(请求的响应状态码),它的值含义:

    • 1** 信息 – 服务器收到请求,需要请求者继续执行操作

    • 2** 成功 – 操作被成功接收并处理

    • 3** 重定向 – 需要进一步的操作以完成请求

    • 4** 客户端错误 – 请求包含语法错误或无法完成请求

    • 5** 服务器错误 – 服务器在处理请求的过程中发生了错误

    一般通过检查响应码 200 OK 判断 AJAX 有没有成功

一般我们会使用异步 AJAX(即 open() 的第三个参数未特别指定或设为 true),在发送请求时,提供一个回调函数负责处理响应,代码大概长这样:

httpRequest.onreadystatechange = function () { 
    if (httpRequest.readyState === 4 && httpRequest.status === 200) { 
        /* 对 httpRequest.response 的一些操作 */ 
    }
}

如果是使用同步 AJAX(即 open() 的第三个参数设为 false),则直接在 send() 方法之后执行要进行的操作即可。但不建议这样做,它的用户体验很糟糕,可能会使页面在请求期间卡住

AJAX 的用法大概就是如此,把所有代码整合到一块是这样的:

var httpRequest = null; 
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
    httpRequest = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE 6 and older
    httpRequest = new ActiveXObject("Microsoft.XMLHTTP")
}
httpRequest.open(method, url, async)
httpRequest.send()
httpRequest.onreadystatechange = function () { 
    if (httpRequest.readyState === 4 && httpRequest.status === 200) { 
        /* 对 httpRequest.response 的一些操作 */ 
    }
}

手动封装 AJAX

这里会用到 Promise 对象【MDN传送门

ajax = (method, url, options) => {
    return new Promise((resolve, reject) => {
        const {success, fail} = options
        const request = new XMLHttpRequest()
        request.open(method, url)
        request.onreadystatechange = () => {
            if(request.readyState === 4){
                if(request.status < 400){
                    resolve.call(null, request.response)
                }else if(request.status >= 400){
                    reject.call(null, request)
                }
            }
        }
        request.send()
    })
}

这个封装只是为了熟悉 Promise 的用法,尚还存在许多问题(post 无法上传数据、不能设置请求头等)

jQuery.ajax

jQuery.ajax() 文档

用法:

  • jQuery.ajax()

  • jQuery.ajax( url [, settings ] )

  • jQuery.ajax( [settings ] )

返回 jqXHR 对象,常用 API:

  • jqXHR.done(function(data, textStatus, jqXHR) {}):一个可供选择的 success 回调选项的构造函数

  • jqXHR.fail(function(jqXHR, textStatus, errorThrown) {}):一种可供选择的 error 回调选项的构造函数

  • jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { }):一种可供选择的 complete 回调选项的构造函数

  • jqXHR.then(function(data, textStatus, jqXHR) {}, function(jqXHR, textStatus, errorThrown) {}):包含了 .done() 和 .fail()方法的功能

axios

axios 文档

参考文章:

Ajax 文档 MDN

Ajax原理一篇就够了


文章作者: April-cl
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 April-cl !
  目录