【H2O2|全栈】JS进阶知识(四)Ajax

目录

前言

开篇语

准备工作

基本概念

原生JS使用AJAX

创建AJAX对象

设置请求方式和地址

设置请求头

发送请求

get方式发送

post方式发送

获取响应数据

AJAX状态码和HTTP状态消息

错误捕获

原生JS封装AJAX方法

[$ 调用AJAX方法](#$ 调用AJAX方法)

结束语


前言

开篇语

本系列博客主要分享JavaScript的进阶语法知识,本期为第三期,主要分享的内容为AJAX请求的基本使用步骤以及原生、jQuery的AJAX封装方法。

从进阶部分开始,我们将脱离原生的JS,使用一些包装的第三方库来完成我们的需求。这些JS库需要在文档的开头引入,暂时的引入格式为script标签加src地址。

与基础部分的语法相比,进阶部分的语法会有较大的差别,注意最好不要混用原生方法与第三方库内容,以免出现不必要的麻烦。

准备工作

软件:【参考版本】Visual Studio Code

**插件(扩展包):**Open in browser, Live Preview, Live Server, Tencent Cloud AI Code Assistant, htmltagwrap

提示:在不熟练的阶段建议关闭AI助手

**第三方JS库:**jquery.min.js

提示:请站内搜索下载、引入方式

**浏览器版本:**Chrome

系统版本: Win10/11/其他非Windows版本

基本概念

AJAX,全名async javascript and XML,中文翻译为"异步JavaScript和XML"。

它是一种使用现有编程语言的新方法,通常用于在不重新加载整个界面的情况下,与服务器后端交换数据并在前端进行部分页面的重新渲染

AJAX默认执行异步机制,即async = true,该参数为false时执行同步操作。

原生JS使用AJAX

创建AJAX对象

原生JS使用AJAX的构造函数创建其对象,它的构造函数为XMLHttpRequest(),中文为可扩展标记语言超文本传输协议请求

创建一个AJAX对象的示例代码如下------

var xhr = new XMLHttpRequest()

设置请求方式和地址

AJAX使用open()方法,告诉AJAX对象以什么方式传输数据,向什么地方发送

发送请求的示例代码如下------

xhr.open("get", "http://localhost:8080/xxx/xxx")

其中,传输方式可以是get,也可以是post。

它们的区别如下------

  • get的参数在url后面 ,而post放在虚拟载体里面;
  • get有大小限制(只能提交少量参数);
  • post在安全性稳定性上比get更强;
  • 应用不同 ,get用于请求数据,post用于提交数据。

设置请求头

请求头相当于一个识别令牌,拥有自己的类型(指定头部)和给服务器识别的口令(提供的值)。

设置请求头的示例代码如下------

xhr.setRequestHeader(key, value)

常见的头部类型有**------**

类型 作用
Authentication(认证) 用于系统进行身份/用户验证的凭据
Authorization(授权) 顺序上在认证之后,不同的用户提供对应的访问系统的权限

特别的,对于POST类型数据,还需要在key处单独设置Content-type,即设置发送数据的格式

此时,对应的值类型如下------

数据类型
application/json 发送json数据
application/x-www-form-urlencoded 发送表单数据
text/plain 发送纯文本
text/html 发送html文本

比如,我们需要设置发送表单类型的数据,就可以像下面这样------

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

发送请求

接下来,我们需要用send()向服务器发送我们设置好的请求信息。

get方式发送

使用该方式发送请求时,我们需要在open()中的url地址的 **?**后拼接需要传输的数据内容。

拼接的字符串通常为下面的格式------

'http://xxx/xxx/xxx?key1=value1\&key2=value2\&...'

然后,我们就可以直接使用AJAX对象发送请求了------

xhr.send()

post方式发送

除了在请求头中声明参数类型之外,post()方式需要设置发送的数据字符串。

拼接参数的实示例代码如下------

var parmas = "key1=" + value1 + "&key2=" + value2

这里我们就不需要把字符串拼到open()里的url中了。

发送请求时,直接将数据字符串放入send()------

xhr.send(parmas)

注意,post方式传递的数据通常为对象格式的字符串,即------

"{

'key1': 'value1',

'key2': 'value2'

}"

获取响应数据

当我们需要获取服务器传来的数据时,有两种事件供我们选择------

事件 作用
onload 加载服务端响应数据
onreadystatechange 侦测 Ajax 状态码并在条件符合时返回数据

用onload方式时,我们直接获取数据字符串即可。

使用xhr的responseText属性获取数据字符串,注意,如果我们需要其中的数据,还得将这个对象格式的字符串转为真正的对象。

在之前的博客中,我们提到了可以使用JSON.parse()方法解析对象格式字符串,因此我们可以用类似下面的方式来获取需要的数据------

var obj = JSON.parse(xhr.responseText)

AJAX状态码和HTTP状态消息

而对于onreadystatechange方式,即检查状态码改变的方式,我们需要用到xhr的readyState属性我们首先需要了解一个请求的五种状态码------

状态码 状态
0 请求未初始化(还没有调用open())
1 请求已经建立,但是还没有发送(还没有调用send())
2 请求已经发送
3 请求正在处理中,通常响应中已经有部分数据可以用了
4 响应已经完成,可以获取并使用服务器的响应了

在到达onreadystatechange这一步之后,至少也是2即以后的状态了,当状态码为4时,接收数据即可。

判断和获取的示例代码如下------

if (xhr.readyState == 4) {

var obj = JSON.parse(xhr.responseText)

console.log(obj);

}

此外,还有一种http状态消息也可以用来判断请求是否成功,比如我们常见的404错误,就是一种状态消息。

一般来说,这个数值在[200, 300)的区间内,说明请求是成功的。

常见的状态消息如下------

消息 含义
200 请求已成功,请求所希望的响应头或数据体将随此响应返回
302 请求的资源临时从不同的 URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的
304 如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾
403 服务器已经理解请求 ,但是拒绝执行
404 请求失败 ,请求所希望得到的资源未被在服务器上发现
500 服务器遇到了一个未曾预料的状况 ,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现

错误捕获

使用onerror方式,来捕获接收数据过程中发生的错误(如网络中断等) ------

xhr.onerror = function () {

// 提示错误信息

}

这里的错误消息也可以是报告HTTP状态消息中的错误类型。

原生JS封装AJAX方法

回顾一下使用AJAX请求数据的全过程,总结起来无非就是下面几步------

  1. 创建AJAX对象 var xhr = new XMLHttpRequest()

  2. 设置请求方式和地址 xhr.open('way', 'url')

  3. 设置请求头 xhr.setRequestHeader(key, headers[key])

  4. POST请求时,需要设置请求体 xhr.setRequestHeader('Content-Type', 'xxx')

  5. 发送请求 xhr.send() / xhr.send(parmas)

  6. 请求状态检查

那么,我们就可以使用一种方式,将上述过程封装起来,每当我们需要使用AJAX请求时,就调用这个函数。

一个示例的封装函数代码如下------

javascript 复制代码
function ajax(url, method = 'GET', data = null, headers = {}, onSuccess = null, onError = null) {
            const xhr = new XMLHttpRequest();
            xhr.open(method, url, true);

            // 设置请求头  
            for (let key in headers) {
                xhr.setRequestHeader(key, headers[key]);
            }

            xhr.onload = function () {
                if (this.status >= 200 && this.status < 300) {
                    // 请求成功  
                    if (onSuccess) {
                        onSuccess(this.responseText, this.status, this);
                    }
                } else {
                    // 请求失败  
                    if (onError) {
                        onError(this.status, this.statusText, this);
                    }
                }
            };


            // 发送POST请求时,需要设置请求体  
            if (method === 'POST' && data) {
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                xhr.send(typeof data === 'string' ? data : Object.keys(data).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])).join('&'));
            } else {
                xhr.send();
            }
        }

data处可以填待传输的数据对象,一般是get方式时填null,post方式时填需要传输的对象。

headers为请求头设置,如果为get方式,则直接按照对象的方式设置即可,比如------

{Authorization: 'aaaaa...'}

如果为post方式,需要写成对象格式字符串------

{'Authorization': 'aaaaa...'}

onSuccess和onError处分别填成功和失败时调用的函数。

$ 调用AJAX方法

$ 对AJAX进行了函数封装,格式和我们上述的封装几乎一致------

$.ajax({

type:请求方式的格式 get post

url:请求的地址

async:是否是异步,默认表示异步

data:发送到服务器的数据

dataType:预期服务器返回的数据类型 json text

headers:设置请求头

success:请求成功时调用此函数

error:请求失败时调用此函数

})

结束语

本期内容到此结束。关于本系列的其他博客,可以查看我的JS进阶专栏。

在全栈领域,博主也只不过是一个普通的萌新而已。本系列的博客主要是记录一下自己学习的一些经历,然后把自己领悟到的一些东西总结一下,分享给大家。

文章全篇的操作过程都是笔者亲自操作完成的,一些定义性的文字加入了笔者自己的很多理解在里面,所以仅供参考。如果有说的不对的地方,还请谅解。

==期待与你在下一期博客中再次相遇==

------临期的【H2O2】

相关推荐
从兄1 分钟前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
m0_656974741 分钟前
C#中的集合类及其使用
开发语言·c#
java1234_小锋3 分钟前
使用 RabbitMQ 有什么好处?
java·开发语言
wjs202411 分钟前
R 数据框
开发语言
肘击鸣的百k路17 分钟前
Java 代理模式详解
java·开发语言·代理模式
捕鲸叉27 分钟前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点43 分钟前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
真的想不出名儿1 小时前
Java基础——反射
java·开发语言
努力编程的阿伟1 小时前
【Java SE语法】抽象类(abstract class)和接口(interface)有什么异同?
java·开发语言
清灵xmf1 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询