程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Ajax

    • 初识Ajax
    • jQuery 的 AJAX 请求
    • 原生 XHR请求
      • 1. 使用 xhr 发起 GET 请求
        • 1.1 了解 xhr 对象的 readyState 属性
        • 1.2 使用 xhr 发起带参数的 GET 请求
      • 2. 使用 xhr 发起 POST 请求
      • 3. JSON
        • 3.1 JSON 语法注意事项
        • 3.2 序列化和反序列化
      • 4. 封装自己的 AJAX 函数
        • 4.1 定义和处理 options 参数
        • 4.2 处理 data 参数
        • 4.3 定义 aini 函数
      • 5. XMLHttpRequest Level2的新特性
        • 5.1 设置 HTTP 请求时限
        • 5.2 FormData 对象管理表单数据
        • 5.2-1 使用 FormData 直接提交数据
        • 5.2-2 使用 FormData 从现有表单获取数据
    • 文件上传
    • Ajax 提交表单数据
    • 跨域与JSONP
  • Ajax
  • Ajax
scholar
2024-07-24
目录

原生 XHR请求

# 原生 XHR请求

原生 XMLHttpRequest(XHR)请求是一个 JavaScript 对象,用于在后台与服务器交换数据,并在不重新加载整个网页的情况下更新网页内容。

# 1. 使用 xhr 发起 GET 请求

步骤:

  1. 创建 xhr 对象
  2. 调用 xhr.open() 函数
  3. 调用 xhr.send() 函数
  4. 监听 xhr.onreadystatechange 事件
// 1. 创建 XHR 对象
var xhr = new XMLHttpRequest();

// 2. 调用 open 函数,指定请求方式与 URL 地址
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks');

// 3. 调用 send 函数,发起 Ajax 请求
xhr.send();

// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
    // 4.1 监听 xhr 对象的请求状态 readyState 以及与服务器响应的状态 status
    if (xhr.readyState === 4 && xhr.status === 200) {
        // 4.2 打印服务器响应回来的数据
        console.log(xhr.responseText); // 在控制台输出响应文本
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 创建 XHR 对象:通过 new XMLHttpRequest() 创建一个新的 XMLHttpRequest 对象,用于发起 HTTP 请求。
  • 调用 open 函数:使用 xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks') 方法指定请求的 HTTP 方法('GET')和目标 URL 地址。
  • 调用 send 函数:xhr.send() 方法发起请求。对于 GET 请求,send 方法没有参数。
  • 监听 onreadystatechange 事件:
    • xhr.readyState 表示请求的状态,4 代表请求已完成。
    • xhr.status 表示 HTTP 响应状态码,200 代表请求成功。
    • xhr.responseText 包含服务器返回的响应数据,使用 console.log() 打印到控制台。

# 1.1 了解 xhr 对象的 readyState 属性

readyState 属性有五个状态,分别是:

  1. 0(UNSENT):请求未初始化
  2. 1(OPENED):请求已打开,但未发送
  3. 2(HEADERS_RECEIVED):请求已发送,正在接收响应头
  4. 3(LOADING):正在接收响应体
  5. 4(DONE):响应接收完成

image-20230626234332091

# 1.2 使用 xhr 发起带参数的 GET 请求

// 使用 xhr 对象发起带参数的 GET 请求时,在调用 xhr.open 时,将参数附加到 URL 地址中
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1');
xhr.send();

// 监听响应
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText);
    }
};
1
2
3
4
5
6
7
8
9
10
11
  • 说明:在 URL 地址后面附加查询参数,例如 http://www.liulongbin.top:3006/api/getbooks?id=1。这种拼接在 URL 后的参数称为查询字符串。

# 2. 使用 xhr 发起 POST 请求

步骤:

  1. 创建 xhr 对象
  2. 调用 xhr.open() 函数
  3. 设置 Content-Type 属性(固定写法)
  4. 调用 xhr.send() 函数,同时指定要发送的数据
  5. 监听 xhr.onreadystatechange 事件
// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest();

// 2. 调用 open 函数,指定请求方式为 POST 和 URL 地址
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook');

// 3. 设置 Content-Type 属性(固定写法)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

// 4. 调用 send 函数,将数据以查询字符串的形式提交给服务器
xhr.send('bookname=水浒传&author=施耐庵&publisher=天津图书出版社');

// 5. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(xhr.responseText);
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 创建 XHR 对象:使用 new XMLHttpRequest() 创建新的 XMLHttpRequest 对象。
  • 调用 open 函数:指定请求方式为 'POST' 和目标 URL 地址。
  • 设置 Content-Type 属性:通过 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') 设置请求头,指明请求体的类型为 URL 编码的表单数据。
  • 调用 send 函数:将数据以查询字符串格式传递给服务器。例如 'bookname=水浒传&author=施耐庵&publisher=天津图书出版社'。
  • 监听 onreadystatechange 事件:处理响应结果,同 GET 请求的处理方式相同。

# 3. JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在计算机和网络之间存储和传输数据。JSON 的数据结构非常简单,主要用于表示对象和数组数据。

对象结构

// JSON 对象结构使用大括号 {} 包裹,数据以键值对的形式表示。
// 键(key)是一个字符串,必须用双引号包裹;值(value)可以是以下类型之一:
// - 数字(例如:123)
// - 字符串(例如:"hello")
// - 布尔值(例如:true 或 false)
// - null
// - 数组(例如:[1, 2, 3])
// - 对象(例如:{"key1": "value1", "key2": "value2"})

var jsonObject = {
    "name": "Alice", // 字符串类型的值
    "age": 25,       // 数字类型的值
    "isStudent": false, // 布尔值类型的值
    "address": null, // null 值
    "hobbies": ["reading", "sports"], // 数组类型的值
    "education": { // 嵌套的对象类型的值
        "degree": "Bachelor",
        "year": 2023
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • 对象结构:JSON 对象是用 {} 包裹的键值对集合。每个键必须是一个用双引号括起来的字符串,每个值可以是六种基本数据类型之一,包括数字、字符串、布尔值、null、数组或对象。

# 3.1 JSON 语法注意事项

// JSON 的语法要求如下:

// ① 属性名必须使用双引号包裹
// 正确: {"name": "Alice"}
// 错误: {name: "Alice"} 

// ② 字符串类型的值必须使用双引号包裹
// 正确: {"message": "Hello, world!"}
// 错误: {"message": 'Hello, world!'}

// ③ JSON 中不允许使用单引号表示字符串
// 正确: {"title": "Book"}
// 错误: {'title': 'Book'}

// ④ JSON 中不能写注释
// 正确: {"data": [1, 2, 3]}
// 错误: {"data": [1, 2, 3], // This is a comment}

// ⑤ JSON 的最外层必须是对象或数组格式
// 正确: {"name": "Alice"}
// 正确: [1, 2, 3]
// 错误: "name": "Alice" // 最外层不是对象或数组

// ⑥ 不能使用 undefined 或函数作为 JSON 的值
// 正确: {"value": null}
// 错误: {"value": undefined}
// 错误: {"func": function() { return "Hello"; }} // 函数不是有效的 JSON 值

// JSON 的作用:用于在计算机和网络之间存储和传输数据。
// JSON 的本质:用字符串来表示 JavaScript 对象或数组数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • 属性名:必须使用双引号(")括起来。
  • 字符串值:也必须使用双引号。
  • 单引号:JSON 不允许使用单引号来表示字符串。
  • 注释:JSON 不允许包含注释;所有注释必须在外部文档中记录。
  • 最外层格式:JSON 数据必须以对象({})或数组([])格式存在。
  • 无效值:undefined 和函数不能作为 JSON 的值。

# 3.2 序列化和反序列化

// 序列化:将 JavaScript 对象转换为 JSON 字符串
var jsObject = {
    name: "Alice",
    age: 25,
    isStudent: false
};

// 使用 JSON.stringify() 方法将对象转换为 JSON 字符串
var jsonString = JSON.stringify(jsObject);
console.log(jsonString);
// 输出: {"name":"Alice","age":25,"isStudent":false}

// 反序列化:将 JSON 字符串转换为 JavaScript 对象
var jsonString = '{"name":"Alice","age":25,"isStudent":false}';

// 使用 JSON.parse() 方法将 JSON 字符串转换为对象
var jsObject = JSON.parse(jsonString);
console.log(jsObject);
// 输出: { name: 'Alice', age: 25, isStudent: false }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 序列化:使用 JSON.stringify() 方法将 JavaScript 对象转换为 JSON 字符串。这在存储或传输数据时非常有用。
  • 反序列化:使用 JSON.parse() 方法将 JSON 字符串转换回 JavaScript 对象。这在接收数据并将其用于应用程序时非常有用。

# 4. 封装自己的 AJAX 函数

自定义 AJAX 函数 aini 允许用户以更简单的方式发起 AJAX 请求。函数接受一个配置对象作为参数,用户可以通过配置对象设置请求类型、URL、数据和成功回调函数。

# 4.1 定义和处理 options 参数

options 参数是传递给 aini 函数的配置对象,包括以下属性:

  1. method:请求的类型(例如 GET 或 POST)。
  2. url:请求的 URL 地址。
  3. data:请求携带的数据。
  4. success:请求成功之后的回调函数。

# 4.2 处理 data 参数

resolveData 函数将 data 对象转化为查询字符串格式,便于在请求中提交给服务器。

/**
 * 处理 data 参数,将对象转换为查询字符串
 * @param {Object} data 需要发送到服务器的数据
 * @returns {string} 返回拼接好的查询字符串,例如 "name=zs&age=10"
 */
function resolveData(data) {
    var arr = []; // 用于存储键值对字符串
    for (var k in data) {
        if (data.hasOwnProperty(k)) { // 确保属性属于对象本身
            arr.push(encodeURIComponent(k) + '=' + encodeURIComponent(data[k]));
        }
    }
    return arr.join('&'); // 生成查询字符串
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • encodeURIComponent:使用 encodeURIComponent 对键和值进行编码,以确保特殊字符(如空格、& 等)在查询字符串中被正确处理。

# 4.3 定义 aini 函数

aini 函数封装了创建和配置 XMLHttpRequest 对象的过程,并处理请求的发送与响应。

/**
 * 自定义 AJAX 函数
 * @param {Object} options 配置对象
 * @param {string} options.method 请求的类型('GET' 或 'POST')
 * @param {string} options.url 请求的 URL 地址
 * @param {Object} options.data 请求携带的数据(仅在 POST 请求中使用)
 * @param {Function} options.success 请求成功后的回调函数
 */
function aini(options) {
    var xhr = new XMLHttpRequest(); // 创建 XMLHttpRequest 对象
    
    // 将 data 对象转化为查询字符串
    var qs = resolveData(options.data || {}); // 如果 data 为 undefined,则传递空对象

    // 判断请求的类型并发起请求
    if (options.method.toUpperCase() === 'GET') {
        // 发起 GET 请求
        xhr.open(options.method, options.url + '?' + qs, true); // true 表示异步请求
        xhr.send(); // 发送请求
    } else if (options.method.toUpperCase() === 'POST') {
        // 发起 POST 请求
        xhr.open(options.method, options.url, true); // true 表示异步请求
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 设置请求头
        xhr.send(qs); // 发送数据
    }

    // 监听请求状态改变的事件
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) { // 请求完成
            if (xhr.status === 200) { // 请求成功
                try {
                    var result = JSON.parse(xhr.responseText); // 解析响应的 JSON 数据
                    options.success(result); // 调用成功回调函数
                } catch (e) {
                    console.error('解析 JSON 失败:', e); // 捕捉并处理 JSON 解析错误
                }
            } else {
                console.error('请求失败,状态码:', xhr.status); // 请求失败时输出状态码
            }
        }
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  • 异步请求:xhr.open() 的第三个参数 true 指定请求为异步,推荐在大多数情况下使用异步请求。
  • Content-Type:对于 POST 请求,设置请求头 Content-Type 为 application/x-www-form-urlencoded。
  • 错误处理:添加了 try-catch 块以捕获 JSON 解析错误,并输出错误信息以帮助调试。
  • 状态码处理:添加了对非200状态码的处理,帮助诊断请求失败的原因。

# 5. XMLHttpRequest Level2的新特性

# 5.1 设置 HTTP 请求时限

在使用 AJAX 请求时,有时请求可能会因为网络问题或者服务器响应延迟而变得非常缓慢。为了避免用户长时间等待,可以设置请求的超时时间。

// 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();

// 设置请求的时限为 3000 毫秒(即 3 秒)
xhr.timeout = 3000; 

// 监听请求超时事件
xhr.ontimeout = function(event) {
    alert('请求超时!'); // 超过设定时间后执行的回调函数
};

// 设置请求的 URL 和请求方式
xhr.open('GET', 'http://www.example.com/api/data', true); // true 表示异步请求

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

// 可以监听其他状态变化事件以获取请求状态
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) { // 请求完成
        if (xhr.status === 200) {
            console.log(xhr.responseText); // 成功时处理响应数据
        } else {
            console.error('请求失败,状态码:', xhr.status); // 处理请求失败
        }
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  • xhr.timeout:设置请求的超时时间。单位是毫秒(ms)。
  • xhr.ontimeout:当请求超时后触发的事件处理函数。
  • xhr.open():用于指定请求的类型(GET/POST)和 URL 地址,并可以设置是否异步请求。
  • xhr.send():发送请求到服务器。

# 5.2 FormData 对象管理表单数据

FormData 对象提供了一种处理表单数据的便捷方法,它可以用来构建表单数据集,模拟用户提交表单的行为。

# 5.2-1 使用 FormData 直接提交数据

// 1. 创建 FormData 对象
var fd = new FormData();

// 2. 为 FormData 对象添加表单项
fd.append('uname', 'zs'); // 添加用户名
fd.append('upwd', '123456'); // 添加密码

// 3. 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();

// 4. 设置请求的 URL 和请求方式
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata', true); // true 表示异步请求

// 5. 直接提交 FormData 对象
xhr.send(fd);

// 监听请求状态改变事件
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) { // 请求完成
        if (xhr.status === 200) {
            console.log(xhr.responseText); // 成功时处理响应数据
        } else {
            console.error('请求失败,状态码:', xhr.status); // 处理请求失败
        }
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  • FormData 对象:用于创建一个可以发送表单数据的对象。
  • fd.append():向 FormData 对象中添加表单字段和对应的值。
  • xhr.send(fd):直接将 FormData 对象作为请求体发送。

# 5.2-2 使用 FormData 从现有表单获取数据

// 获取表单元素
var form = document.querySelector('#form1');

// 监听表单的 submit 事件
form.addEventListener('submit', function(e) {
    e.preventDefault(); // 阻止表单的默认提交行为

    // 根据表单创建 FormData 对象,会自动填充表单数据
    var fd = new FormData(form);

    // 创建 XMLHttpRequest 对象
    var xhr = new XMLHttpRequest();

    // 设置请求的 URL 和请求方式
    xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata', true); // true 表示异步请求

    // 发送 FormData 对象
    xhr.send(fd);

    // 监听请求状态改变事件
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) { // 请求完成
            if (xhr.status === 200) {
                console.log(xhr.responseText); // 成功时处理响应数据
            } else {
                console.error('请求失败,状态码:', xhr.status); // 处理请求失败
            }
        }
    };
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  • FormData(form):创建一个 FormData 对象,并从表单中自动填充数据。
  • e.preventDefault():阻止表单的默认提交行为,使得 AJAX 提交得以替代传统的表单提交。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
jQuery 的 AJAX 请求
文件上传

← jQuery 的 AJAX 请求 文件上传→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式