AJAX
一、Ajax是什么
Ajax(Asynchronous JavaScript and XML)是一种用于创建动态网页应用程序的技术。它使得网页能够在不重新加载整个页面的情况下,与服务器进行异步数据交换。Ajax的核心理念是提高用户体验,通过快速响应和交互,使得网页应用看起来更流畅。
Ajax的工作原理主要依赖于JavaScript、XML(或JSON)、HTML和CSS等技术。用户在网页上进行操作时,JavaScript可以通过XMLHttpRequest对象发送请求到服务器,并获取数据。获取的数据通常是XML格式,但现在越来越多的应用选择使用JSON格式,因为它更轻量且易于处理。
1.1名词解释
1.1.1 服务器
服务器是一种为其他计算机或设备(称为客户端)提供服务的计算机系统。它可以处理各种请求,如存储数据、运行应用程序、管理网络资源等,并向客户端提供相应的响应。
XMLHttpRequest 是一种在浏览器中使用的 API,用于在不重新加载整个网页的情况下,与服务器进行数据交换。它是 Ajax 技术的核心之一,通过它,网页可以在后台发送 HTTP 请求,并接收来自服务器的响应,用户无需等待整个页面刷新就可以看到更新的内容。
1.1.2 同步与异步
Web 开发中,异步和同步是两种处理任务的方式,主要区别在于它们如何执行任务以及等待结果。
function syncTask() {
console.log("同步任务开始");
// 模拟一个耗时任务(例如:阻塞型的计算任务)
for (let i = 0; i < 5; i++) {
sleep(1000 * (i + 1)).then(() => {
console.log(`同步任务执行中... 第 ${i + 1} 次`);
});
}
console.log("执行2");
}
// 模拟睡眠功能
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
console.log("程序开始");
syncTask();
console.log("程序结束");
1. 同步(Synchronous)
- 执行方式:同步操作是按照顺序执行的,一个任务执行完后,才会开始下一个任务。
- 等待结果:在执行一个任务时,程序会一直等待这个任务完成,然后再执行接下来的任务。
- 示例:一个网页加载内容时,如果使用同步的方式,所有请求必须等待前一个完成后才能继续。假设加载图片、文本等资源时,每个资源的请求都是逐个进行的。
同步部分
console.log("同步任务开始");
console.log("执行2");
这些操作是立即执行的,并且会阻塞后续代码的执行,直到它们完成
2. 异步(Asynchronous)
- 执行方式:异步操作不会等待当前任务完成,而是立即执行下一个任务。当异步任务完成时,它会通过回调函数或 Promise 通知程序。
- 等待结果:异步操作允许程序在等待一个耗时操作完成的同时继续执行其他任务,极大地提升了效率,特别是在处理 I/O 操作时(例如,网络请求、数据库查询)。
- 示例:网页加载时,可以同时请求多个资源,资源完成加载后再更新到页面上,而无需等待其他资源完成。
sleep(1000 * (i + 1)).then(() => { ... });
这部分使用了 Promise 和 setTimeout 来模拟异步操作。当 sleep 函数被调用时,它返回一个 Promise 对象,这个对象会在指定的时间后通过调用 resolve 而变为 fulfilled 状态。then 方法注册了一个回调函数,这个函数将在 Promise 变为 fulfilled 状态时执行。因此,console.log 的调用是在未来的某个时间点才会发生的,不会阻塞当前的执行流程。
3. 异步 vs 同步 场景
- 同步:适合那些必须按顺序执行,不能并行的任务,例如需要读取文件的每一行并按顺序处理。
- 异步:适合那些可以并行处理的任务,尤其是需要等待外部资源的操作,比如网络请求、数据库访问等。
4. 异步在 Web 开发中的常见应用:
- AJAX 请求:允许在不刷新页面的情况下从服务器获取数据。
- 事件监听:如用户点击按钮后触发异步事件。
- Promises 和 async/await:这是现代 JavaScript 中实现异步操作的主流方式,简化了回调地狱问题。
简单来说,同步意味着程序要等某个操作完成,而异步则允许程序在等待操作结果时做其他事情。
1.2 URL 统一资源定位符
URL是“Uniform Resource Locator”的缩写,中文称为统一资源定位符。它是互联网上用来定位和访问资源(如网页、图片、视频等)的地址。一个典型的URL由几个部分组成,包括协议(如HTTP或HTTPS)、域名(如www.example.com)、路径(指向特定资源的位置)以及可选的查询参数。例如:
https://www.example.com/path/to/resource?query=parameter
在这个例子中:
https
是协议www.example.com
是域名/path/to/resource
是路径?query=parameter
是查询参数。
URL的作用是帮助用户或计算机找到互联网上的特定资源。
1.2.1 URL - 查询参数
URL查询参数是附加在URL后面的部分,用于传递额外的信息给服务器。它们通常以问号(?
)开始,后面跟着一个或多个参数,每个参数由键和值组成,键和值之间用等号(=
)连接,而不同的参数则用和号(&
)分隔。
https://www.example.com/search?q=c+programming&sort=latest&page=2
?
表示查询参数的开始。q=c+programming
是第一个参数,其中q
是键,c+programming
是值。sort=latest
是第二个参数。page=2
是第三个参数。
查询参数常用于网页表单提交、过滤和排序数据等场景。通过这些参数,用户可以与网站的功能进行交互,服务器可以根据传递的参数返回相应的数据。
1.2.2 axios-查询参数
在使用 Axios 进行 HTTP 请求时,查询参数是 URL 中用于传递额外信息的一部分。Axios 允许你方便地设置这些查询参数,以便在请求中包含所需的数据。
方法 1:使用 params
选项
通过对象的形式传递查询参数,Axios 会自动将它们转换为 URL 查询字符串。
import axios from 'axios';
const params = {
q: 'c programming',
sort: 'latest',
page: 2,
};
axios.get('https://www.example.com/search', { params })
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
方法 2:手动构建查询字符串
手动构建查询字符串,并将其附加到 URL 中。这在某些情况下可能更灵活。
import axios from 'axios';
const queryString = 'q=c+programming&sort=latest&page=2';
const url = `https://www.example.com/search?${queryString}`;
axios.get(url)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
方法 3:使用 URLSearchParams 对象
使用 `URLSearchParams` 对象来更方便地处理查询参数,尤其是需要编码特殊字符时。
import axios from 'axios';
const params = new URLSearchParams();
params.append('q', 'c programming');
params.append('sort', 'latest');
params.append('page', 2);
axios.get(`https://www.example.com/search?${params.toString()}`)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
总结
- 使用
params
:最简单直接的方式,Axios 会自动处理。 - 手动构建查询字符串:灵活但需要自己处理格式。
- 使用
URLSearchParams
:适合需要编码特殊字符的场景。
二、axios
Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
2.1 安装 Axios
如果你在 Node.js 环境中使用,可以通过 npm 安装:
npm install axios
如果你在浏览器中使用,可以直接通过 CDN 引入:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
2.2 使用 Axios
1. 发送 GET 请求
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error fetching data:', error);
});
2. 发送 POST 请求
axios.post('https://api.example.com/data', {
name: 'John Doe',
age: 30
})
.then(response => {
console.log('Data saved:', response.data);
})
.catch(error => {
console.error('Error saving data:', error);
});
3. 添加请求和响应拦截器
// 添加请求拦截器
axios.interceptors.request.use(config => {
// 在发送请求之前做些什么
console.log('Request sent:', config);
return config;
}, error => {
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(response => {
// 对响应数据做点什么
console.log('Response received:', response);
return response;
}, error => {
return Promise.reject(error);
});
4. 处理错误
Axios 会返回一个 Promise,因此可以通过 .catch()
方法处理错误。
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
if (error.response) {
// 请求已发出,但服务器响应了状态码
console.error('Error response:', error.response);
} else if (error.request) {
// 请求已发出,但没有收到响应
console.error('Error request:', error.request);
} else {
// 其他错误
console.error('Error:', error.message);
}
});
5. 取消请求
可以使用 Axios 的 CancelToken 来取消请求:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('https://api.example.com/data', {
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled:', thrown.message);
} else {
// 处理错误
}
});
// 取消请求
cancel('Operation canceled by the user.');
三、在网络编程和API交互中,常用的请求方法主要包括以下几种:
-
GET: 获取数据
- 用于从服务器请求数据。通常用于获取资源,不应该产生副作用。
- 例如:请求一个网页或获取用户信息。
-
POST: 数据提交
- 用于向服务器发送数据,通常用于创建新资源或提交数据。
- 例如:提交表单数据或上传文件。
-
PUT: 修改数据(全部)
- 用于更新现有资源的全部内容。通常需要提供完整的资源表示。
- 例如:更新用户的所有信息。
-
PATCH: 修改数据(部分)
- 用于部分更新现有资源,只需要提供需要更改的字段。
- 例如:只更新用户的邮箱地址。
-
DELETE: 删除数据
- 用于请求删除指定的资源。
- 例如:删除某个用户或某个文件。
-
HEAD:
- 类似于GET请求,但只请求响应的头部信息,而不获取具体内容。
- 例如:检查资源是否存在或获取元数据。
-
OPTIONS:
- 用于请求支持的HTTP方法和其他选项,以便了解服务器支持哪些功能。
- 例如:查看某个资源允许的操作。
axios 请求配置
使用 Axios 进行 HTTP 请求时,可以通过配置对象来设置请求的各种参数。以下是一些常用的 Axios 请求配置选项:
1. 基本配置
axios({
method: 'get', // 请求方法(get, post, put, delete等)
url: 'https://api.example.com/data', // 请求 URL
headers: { // 请求头
'Content-Type': 'application/json',
'Authorization': 'Bearer token',
},
params: { // URL 参数
id: 123,
},
data: { // 请求体数据(通常用于 POST 或 PUT 请求)
name: 'John Doe',
age: 30,
},
timeout: 1000, // 请求超时设置(毫秒)
responseType: 'json', // 响应类型 (json, blob, document, text, stream)
});
2. 创建实例
你可以创建一个 Axios 实例并为其设置默认配置:
const instance = axios.create({
baseURL: 'https://api.example.com', // 基础 URL
timeout: 1000, // 请求超时设置
headers: {
'Content-Type': 'application/json',
},
});
// 使用实例发起请求
instance.get('/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
3. 拦截器
你可以使用拦截器来处理请求或响应:
// 请求拦截器
axios.interceptors.request.use(config => {
// 在发送请求之前做些什么
return config;
}, error => {
return Promise.reject(error);
});
// 响应拦截器
axios.interceptors.response.use(response => {
// 对响应数据做些什么
return response;
}, error => {
return Promise.reject(error);
});
4. 错误处理
在请求中,你可以使用 .catch
方法处理错误:
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('请求出错:', error);
});
5. 并发请求
你可以使用 axios.all
来进行并发请求:
axios.all([
axios.get('/endpoint1'),
axios.get('/endpoint2'),
])
.then(axios.spread((response1, response2) => {
console.log('Response 1:', response1.data);
console.log('Response 2:', response2.data);
}))
.catch(error => {
console.error('请求出错:', error);
});
这些配置选项可以帮助你根据不同的需求来设置 Axios 请求。
四、HTTP - 超文本传输协议
HTTP(超文本传输协议,Hypertext Transfer Protocol)是一种用于在Web上进行数据传输的协议。
它是客户端(如浏览器)和服务器之间通信的基础,主要用于请求和传输网页、图像、视频等各种类型的数据。
HTTP(Hypertext Transfer Protocol)是一种用于在客户端和服务器之间传输数据的应用层协议。HTTP协议基于请求/响应模型,其中客户端发送请求报文(Request Message),服务器响应并返回响应报文(Response Message)。每个HTTP报文通常包含起始行、头部、空行和可选的消息主体四个部分。以下是HTTP协议中请求报文和响应报文的完整结构描述。
4.1、HTTP请求报文结构
1. 起始行(Request Line)
起始行用于指定客户端向服务器发起的请求类型、目标资源以及协议版本。
请求方法 请求URI 协议版本
GET /index.html HTTP/1.1
-
请求方法(Request Method):表示客户端要对资源执行的操作,常见的方法包括:
GET
:请求指定资源的内容。POST
:向服务器提交数据。PUT
:更新资源。DELETE
:删除资源。HEAD
:仅获取响应头而不返回消息体。OPTIONS
:查询服务器支持的请求方法。
-
请求URI(Request URI):指示请求的目标资源的路径或地址。可以是绝对路径(
/index.html
)或查询字符串(/search?q=abc
)。 -
协议版本(HTTP Version):指示HTTP协议的版本号,如
HTTP/1.1
或HTTP/2
。
2. 请求头部(Request Headers)
请求头部包含多个键值对,用来描述请求的附加信息
Header-Name: Header-Value
常见请求头部字段包括:
- Host:表示请求资源所在的主机名及端口,如
Host: www.example.com
。 - User-Agent:说明客户端的类型,如浏览器或操作系统信息。
- Accept:指示客户端能够接受的MIME类型,如
Accept: text/html
。 - Content-Type:指示请求体的媒体类型,如
Content-Type: application/json
。 - Authorization:携带认证信息,如
Authorization: Bearer <token>
。
3. 空行(CRLF)
在请求头和请求体之间使用一个空行(即\r\n
)来分隔,请求头部的结束以此标识。
4. 请求体(Request Body)
请求体用于携带需要发送给服务器的数据。只有像POST
、PUT
等操作才需要请求体,如上传文件、提交表单等。
例如,一个带有JSON数据的POST
请求报文:
POST /api/v1/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 55
{
"username": "example",
"password": "password123"
}
4.2 、HTTP响应报文结构
1. 起始行(Status Line)
响应报文的起始行包含协议版本、状态码和状态短语,格式如下:
HTTP-Version Status-Code Status-Phrase
HTTP/1.1 200 OK
- 协议版本(HTTP Version):指示HTTP协议版本号,如
HTTP/1.1
。 - 状态码(Status Code):用于表示响应的结果,如
200
表示成功,404
表示未找到资源。 - 状态短语(Status Phrase):对状态码的描述,如
OK
、Not Found
。
常见状态码及其含义:
- 1xx(信息性状态码):表示请求已被接收,正在处理,如
100 Continue
。 - 2xx(成功状态码):表示请求已成功处理,如
200 OK
。 - 3xx(重定向状态码):表示需要进一步操作才能完成请求,如
301 Moved Permanently
。 - 4xx(客户端错误状态码):表示请求有错误,如
400 Bad Request
,404 Not Found
。 - 5xx(服务器错误状态码):表示服务器未能完成请求,如
500 Internal Server Error
。
2. 响应头部(Response Headers)
响应头部包含描述响应的附加信息,格式同样为键值对形式:
Header-Name: Header-Value
常见响应头部字段包括:
- Date:响应的日期和时间,如
Date: Wed, 21 Oct 2015 07:28:00 GMT
。 - Server:服务器软件的信息,如
Server: Apache/2.4.1
。 - Content-Type:响应体的MIME类型,如
Content-Type: text/html; charset=UTF-8
。 - Content-Length:响应体的长度,如
Content-Length: 348
。 - Set-Cookie:设置客户端Cookie,如
Set-Cookie: sessionId=abc123; Path=/; HttpOnly
。
3. 空行(CRLF)
与请求报文一样,响应头部和响应体之间使用一个空行(\r\n
)分隔。
4. 响应体(Response Body)
响应体用于存放实际的数据内容,比如HTML、JSON、图片等。通常,响应体的内容由Content-Type
头部字段指示。
例如,一个成功的HTML响应报文:
HTTP/1.1 200 OK
Date: Wed, 21 Oct 2015 07:28:00 GMT
Server: Apache/2.4.1
Content-Length: 44
Content-Type: text/html
<html><body><h1>Hello, World!</h1></body></html>
五、快速收集表表单 form-serialize 插件
- 首先,在你的HTML文件中引入
form-serialize
插件:
<script src="./lib/form-serialize.js"></script>
- 然后,在你的JavaScript代码中,使用以下方法来收集表单数据:
const form = document.querySelector('your-form-selector');
const formData = serialize(form, { hash: true });
console.log(formData);
示例
( 1 ) 表单
<form action="javascript:;" class="example-form">
<input type="text" name="username">
<br>
<input type="text" name="password">
<br>
<input type="button" class="btn" value="提交">
</form>
***( 2 ) script ***
<script src="./lib/form-serialize.js"></script>
<script>
document.querySelector('.btn').addEventListener('click', () => {
/**
* 使用serialize函数,快速收集表单元素的值
*
* 参数1:要获取哪个表单的数据
* 表单元素设置name属性,值会作为对象的属性名
* 建议name属性的值,最好和接口文档参数名一致
*
* 参数2:配置对象
* hash 设置获取数据结构
* - true:JS对象(推荐)一般请求体里提交给服务器
* - false: 查询字符串
* empty 设置是否获取空值
* - true: 获取空值(推荐)数据结构和标签结构一致
* - false:不获取空值
*/
const form = document.querySelector('.example-form')
const data = serialize(form, {hash: true, empty: true})
// const data = serialize(form, { hash: false, empty: true })
// const data = serialize(form, { hash: true, empty: false })
console.log(data)
})
</script>
(3)区别
- 1
const data = serialize(form, {hash: true, empty: true})
hash: true: 表示序列化后的数据将以对象(hash)的形式返回。
empty: true: 表示空值(如空字符串、null 等)也会被包含在序列化的结果中。
- 2
const data = serialize(form, { hash: false, empty: true })
这行代码中 hash: false 意味着序列化后的数据不会以对象形式返回,但 empty 的值写错了,应该是 true 或 false 而不是 true。如果 empty 的值为 true,则表示空值会被包含;如果是 false 则不包含。
- 3
const data = serialize(form, { hash: true, empty: false })
hash: true: 同样表示序列化后的数据将以对象形式返回。
empty: false: 表示空值不会被包含在序列化的结果中。
总结
hash 选项决定了返回的数据结构是对象还是其他形式(如字符串)。
empty 选项决定了是否将空值包含在序列化结果中。
第二种代码由于 empty 的值错误,实际运行时可能会抛出错误。