百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程文章 > 正文

前端面试题——手写实现 ajax 前端手写代码

qiyuwang 2024-10-21 09:40 19 浏览 0 评论

无论是通过模板引擎加载的,还是前后端分离的项目,我们都可以通过 ajax 来实现页面的无刷新请求数据。比如我们有个实时数据要展示,肯定是页面图表局部刷新,谁也不期待整个页面反复加载。

ajax 在我们的开发工作中已经司空见惯,几乎所有我们频繁使用的库和框架(如 jQuery、Vue、React)都提供了经过完善封装后的 ajax 方法,我们习惯于使用$ajax()、$axios、fetch来帮我们实现http请求数据,我们似乎忘记原生的该怎么写了。来吧,我们重温原理,温故而知新。

01

手写AJAX的步骤

手写ajax并没有一个统一的标准,一般的步骤是分以下几步:

  • 创建XMLHttpRequest对象
  • 打开连接
  • 发送请求
  • 响应

也可以参照w3school:

https://www.w3schools.com/xml/ajax_intro.asp

02

步骤简要描述

1. 创建XMLHttpRequest对象

我们常用的 ajax 就是通过 XMLHttpRequest 对象实现的,这个对象有很多的属性和事件,在使用之前我们需要先将它实例化。

let xhr;
if ((window as any).XMLHttpRequest) {
  xhr = new XMLHttpRequest();
} else {
  //兼容IE
  xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

2. 连接与发送

在通过send方法发送请求后,xhr 对象在收到响应数据时会自动填充到其对应的属性中,xhr 具有以下常用属性:

responseText:请求返回的数据内容
responseXML:如果响应内容是 "text/xml""application/xml",这个属性将保存响应数据的 XML DOM文档

status:响应的HTTP状态,如 200 304 404 等
statusText:HTTP状态说明
readyStatus:请求/响应过程的当前活动阶段
timeout:设置请求超时时间

//连接与发送
let method=options.type.toUpperCase();
if ('GET'===method) {
  xhr.open('get', `${options.url}?${queryString}`, options.async);
  xhr.send();
} else if ('POST'===method) {
  xhr.open('post', options.url, options.async);
  xhr.send(options.data);
}


3. 接收响应

readyStatus的值会随着请求各阶段的变化而改变,其一共有 5 个值:

xhr.readyStatus==0 尚未调用 open 方法
xhr.readyStatus==1 已调用 open 但还未发送请求(未调用 send)
xhr.readyStatus==2 已发送请求(已调用 send)
xhr.readyStatus==3 已接收到请求返回的数据
xhr.readyStatus==4 请求已完成

当readyStatus的状态发生改变时,会触发 xhr 的事件onreadystatechange,于是我们就可以在这个方法中,对接收到的数据进行处理

//接收
xhr.onreadystatechange = () => {
  if (xhr.readyState === 4) {
    //clearTimeout(timer);
    if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
      resolve(xhr.responseText);
    } else {
      reject(xhr.status);
    }
  }
}

03

完整示例代码

1. 我们看一下完整代码

这里函数参数我采用了TypeScript, TypeScript使我们的代码可维护性和可读性变得非常好,本身的类型系统就是一个最好的文档,我们在编译阶段就可以发现错误。该 ajax 方法通过 我们上一篇文章提到的Promise A+ 规范的简单应用 方式实现回调。

interface Options {
    url: string;
    method?: string;
    data: any;
    timeout?: number;
    headers?:object;
    async?:boolean;
}

function toQueryString(params) {
    let dataArr = [];
    params.t = Math.random();
    for (let key in params) {
        dataArr.push(`${key}=${encodeURIComponent(params[key])}`);
    }
    return dataArr.join('&');
}

export function ajax(options: Options={method:'GET',data:{},url:'',timeout:10000,async:true}) {
    return new Promise((resolve, reject) => {
    	
        if (!options.url) throw Error('the url is required!');

        let xhr;
        if ((window as any).XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else {
        	  //兼容IE
            xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }
 
        //请求参数拼接       
        const queryString=toQueryString(options.data);
        const headers=options.headers||{'Content-Type':'application/json;charset=UTF-8'};
        
        //请求头设置
        Object.keys(headers).forEach(key=>{
        	xhr.setRequestHeader(key,headers[key]);
        })
        
        //超时处理
        xhr.timeout=options.timeout;
        xhr.ontimeout=()=>{
        	reject('请求超时');
        }
        //if (options.timeout) {
        //    timer = setTimeout(() => {
        //        xhr.abort();
        //        reject('超时');
        //    }, options.timeout)
        //}
        
        //连接与发送
        let method=options.type.toUpperCase();
        if ('GET'===method) {
            xhr.open('get', `${options.url}?${queryString}`, options.async);
            xhr.send();
        } else if ('POST'===method) {
            xhr.open('post', options.url, options.async);
            xhr.send(options.data);
        }
    
        //接收
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                //clearTimeout(timer);
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                    resolve(xhr.responseText);
                } else {
                    reject(xhr.status);
                }
            }
        }
    });
}

04

如何使用

1. 使用方式

ajax({
    url: 'your request url',
    method: 'get',
    async: true,
    timeout: 1000,
    data: {
        test: 1,
        aaa: 2
    }
}).then(res => {
    console.log('请求成功: ' + res)
}).catch(err=>{
    console.error('请求失败: ' + err)
})     


学无止境,觉得不错的话,请关注前端琅琊阁!

相关推荐

windows开启telnet服务,检测远程服务端口是否可以连通

本文介绍windwos开启telnet服务,telnet服务一般可以用于检测远程主机的某个端口服务是否可以连通,在日常的工作中,我们经常会遇到在本地的windows检测远程服务端口是否可以连通。win...

仅在Web登录新华三交换机条件下启用设备Telnet登录方式

概述Web登录新华三交换机可以在“网络-服务”页面中启用设备Telnet服务或SSH服务,也可以在“设备-管理员”设置管理员用户的可用服务,然而,在设备Web页面中,无法设置lineVTY用户线【l...

思科交换机,路由器如何关闭telnet 开启ssh服务

SSH为建立在应用层基础上的安全协议。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。今天我们就来说说思科交换机,路...

智能化弱电行业常用的DOS命令,掌握了你也能成为...

前言在做智能化弱电项目时,前端摄像头设备安装结束后,我们会对网络摄像头进行调试,调试过程中会遇到前端摄像头没有图像或者图像出来了画面卡顿的现象。我们会采用ping命令来测试网络的连通性和网络承载能力。...

「干货」eNSP模拟器之配置Telnet登录

配置说明:配置Telnet,使R2(模拟PC)通过SW1登录到R1进行管理和配置。操作步骤:system-view##进入系统视图[Huawei]sysnameR1##改名为R1[R1]int...

win11开启telnet服务怎么操作 win11打开telent指令是什么

telnet服务是我们在进行远程连接的时候,必须要打开的一项功能。但是有不少用户们不清楚在windows11系统中怎么开启telnet服务。今天小编就使用详细的图文教程,来给大家说明一下打开telen...

华三(H3C)交换机Telnet的远程登陆

一,配置交换机管理IP[SW1]vlan20//创建管理vlan[SW1]interfacevlan20//进入vlan接口[SW1-Vlanif20]ipaddress192.168....

win10 telnet命令怎么查看端口是否打开

可能大家也会遇到这个问题,win10telnet命令查看端口是否打开的步骤是什么?具体方法如下:1、键盘输入快捷键WIN+R,打开运行窗口。2、输入cmd,点击确定按钮。3、弹出cmd命令行窗...

Windows 7如何打开Telnet功能(win7系统打开telnet)

Windows7默认安装后是没有开启telnet客户端功能的,例如,我们在开始菜单中输入cmd,然后使用telnet命令,会弹出下图提示:‘telnet’不是内部或外部命令,也不是可运行程序或批处理文...

为锐捷路由器交换机开启web和telnet,实现轻松管理

笔者上一篇文章写了关于锐捷二层交换机配置教程,那么接下来讲一下锐捷的路由交换设备配置web、telnet技巧。同样,今天的教程也是基于命令行,比较简单,适合新手小白进行学习。准备工作配置前准备:con...

一文学会telnet命令的用途和使用方法

Telnet是一个古老的远程登录协议,可以让本地计算机获得远程计算机的工作能力。它采用了TCP的可靠连接方式,可以连接任何网络互通的远程计算机。不过由于它采用了明文传输方式,存在安全风险,目前已经很少...

Telnet命令是什么?如何使用?(telnet命令在哪里开启)

telnet命令是一个常用的远程登陆工具,使用它,我们可以快捷地登陆远程服务器进行操作。那么如何使用telnet命令呢?首先,我们需要打开telnet功能,任何电脑默认是关闭此功能的,开启方式如下:打...

win11系统如何开启telnet服务(拷贝版本)

  我们要知道,Telnet协议是Internet远程登陆服务的标准协议,可以使用户在本地计算机上完成远程主机的工作,不过对于一些刚接触win11中文版系统的用户来说,可能还不知道telnet服务在哪...

如何开启telnet客户端(如何开启telnet服务)

Telnet协议是TCP/IP协议家族中的一员,是Internet远程登陆服务的标准协议和主要方式,Telnet是常用的远程控制Web服务器的方法。工作中经常用到telnet客户端,但在windows...

Telnet 是什么,如何启用它?(telnet有什么用)

对于Internet等TCP/IP网络,Telnet是一个终端仿真程序。Telnet软件在您的系统上运行并将您的个人计算机链接到网络服务器。它将所有数据转换为纯文本这一事实被认为是易受...

取消回复欢迎 发表评论: