Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 深入系列之实现 AJAX,以及使用 Promise 封装 AJAX 请求 #108

Open
yuanyuanbyte opened this issue Nov 24, 2021 · 0 comments

Comments

@yuanyuanbyte
Copy link
Owner

yuanyuanbyte commented Nov 24, 2021

本系列的主题是 JavaScript 深入系列,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末

如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。

简洁全面的手写AJAX,以及用Promise封装AJAX请求

前言

原生js实现Ajax,本文用最简洁的脉路,帮你梳理前端经典面试“手写ajax”,然后再告诉你廖雪峰是如何使用Promise封装ajax!!!

手写AJAX

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
    if (xhr.readyState !== 4) return;
    if (xhr.status === 200) {
        console.log(xhr.responseText)
        // do what
    } else {
        new Error(xhr.statusText)
    }
};
xhr.open("GET", url, true);
xhr.send();

实现AJAX请求的步骤:

  1. 创建 XMLHttpRequest 对象

  2. 设置状态监听函数

  3. 规定请求的类型、URL 以及是否异步处理请求

  4. 将请求发送到服务器

介绍AJAX

AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML)。简单点说,就是使用 XMLHttpRequest 对象与服务器通信。

AJAX最主要的两个特性:

  • 在不重新加载页面的情况下发送请求给服务器。
  • 接受并使用从服务器发来的数据。

步骤详解

// 1.创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
// 2.设置状态监听函数
xhr.onreadystatechange = function () {// 状态发生变化时,触发回调函数
    if (xhr.readyState !== 4) return;
    if (xhr.status === 200) {
        // 成功:从服务器获取数据,通过responseText拿到响应的文本
        console.log(xhr.responseText)
        // do what
    } else {
        // 失败,根据响应码判断失败原因
        new Error(xhr.statusText)
    }
};
// 3.规定请求的类型、URL 以及是否异步处理请求
xhr.open("GET", url, true);
// 4.将请求发送到服务器
xhr.send();

创建 XMLHttpRequest 对象

创建 XMLHttpRequest 对象的语法

var xhr = new XMLHttpRequest();

向服务器发送请求

将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open()send() 方法:

xhr.open("GET",url,true);
xhr.send();

open(method,url,async) 方法 规定 请求的类型URL 以及 是否异步处理请求

  • method:请求的类型;GET 或 POST
  • url:文件在服务器上的位置
  • async:true(异步)或 false(同步),默认值为true

send(string) 方法 将请求发送到服务器。

  • string:仅用于 POST 请求

如果需要像获取 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:

xhr.open("POST",url,true); 
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
xhr.send("fname=Henry&lname=Ford");

设置状态监听函数

当请求被发送到服务器时,我们需要执行一些基于响应的任务,处理服务器响应。

每当 readyState 改变时,就会触发 onreadystatechange 事件。

readyState 属性存有 XMLHttpRequest 的状态信息。

下面是 XMLHttpRequest 对象的三个重要的属性:

onreadystatechange - 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。

readyState - 存有 XMLHttpRequest 的状态。请求状态 从 0 到 4 发生变化。

  • 0: 请求未初始化
  • 1: 服务器连接已建立
  • 2: 请求已接收
  • 3: 请求处理中
  • 4: 请求已完成,且响应已就绪

status - HTTP响应码

  • 200: "OK"
  • 404: 未找到页面

每当 readyState 发生变化时就会调用 onreadystatechange 函数。

当 readyState 等于 4 且状态为 200 时,表示响应已就绪:

// 设置状态监听函数
xhr.onreadystatechange = function () {// 状态发生变化时,触发回调函数
    if (xhr.readyState !== 4) return;
    if (xhr.status === 200) {
        // 成功:从服务器获取数据,通过responseText拿到响应的文本
        console.log(xhr.responseText)
        // do what
    } else {
        // 失败,根据响应码判断失败原因
        new Error(xhr.statusText)
    }
};

注意: onreadystatechange 事件被触发 4 次(0 - 4), 分别是: 0-1、1-2、2-3、3-4,对应着 readyState 的每个变化。

错误监控处理

XMLHttpRequest.statusText属性返回一个字符串,表示服务器响应的状态提示。不同于status属性,该属性包含整个状态信息,比如“OK”和“Not Found”。如果请求的状态readyState的值为"0"或者"1",则这个属性的值将会是一个空字符;如果服务器没有返回状态提示,该属性的值默认为“OK”。该属性为只读属性。

从服务器获取数据

当 readyState 等于 4 且状态为 200 时,表示响应已就绪,这个时候就可以用服务器返回的数据做任何你想做的了。

可以通过 xhr.responseText去访问这些数据:

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

使用Promise封装AJAX

// Promise封装Ajax请求
function ajax(method, url, data) {
    var xhr = new XMLHttpRequest();
    return new Promise(function (resolve, reject) {
        xhr.onreadystatechange = function () {
            if (xhr.readyState !== 4) return;
            if (xhr.status === 200) {
                resolve(xhr.responseText);
            } else {
                reject(xhr.statusText);
            }

        };
        xhr.open(method, url);
        xhr.send(data);
    });
}

使用上面封装好的ajax发起一个请求:

ajax('GET', '/api/categories').then(function (data) {
    // AJAX成功,拿到响应数据
    console.log(data);
}).catch(function (status) {
    // AJAX失败,根据响应码判断失败原因
    new Error(status)
});

参考

查看原文

查看全部文章

博文系列目录

  • JavaScript 深入系列
  • JavaScript 专题系列
  • JavaScript 基础系列
  • 网络系列
  • 浏览器系列
  • Webpack 系列
  • Vue 系列
  • 性能优化与网络安全系列
  • HTML 应知应会系列
  • CSS 应知应会系列

交流

各系列文章汇总:https://github.com/yuanyuanbyte/Blog

我是圆圆,一名深耕于前端开发的攻城狮。

weixin

@yuanyuanbyte yuanyuanbyte changed the title JavaScript 深入系列之实现 AJAX,使用 Promise 封装 AJAX 请求 JavaScript 深入系列之实现 AJAX,以及使用 Promise 封装 AJAX 请求 Dec 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant