Ajax即是异步的JavaScript和XML,Ajax其实就是浏览器与服务器之间的一种异步通信方式。
异步的JavaScript
它可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,在这种情况下,浏览器可以做自己的事情。直到成功获取响应后,浏览器才开始处理响应数据。
Ajax就是在浏览器不重新加载网页的情况下,对页面的某部分进行更新。
一:实现ajax
json文件中的对象键名一定要用双引号包裹,如果属性值里面有字符串,也需要用双引号包裹。
//test.josn的代码
{
"reply":"我收到啦!"
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
};
xhr.open('GET', 'text.json', true);
xhr.send(null);
二:完整流程比喻
把这个过程比作点外卖:
1.创建一个xhr对象
2.使用xhr的readystatechange属性,判断Ajax的状态码
3.判断HTTP的状态码
4.xhr.open()准备发送请求
5.xhr.send()发送请求
-
new XMLHttpRequest()- 拿出手机准备点餐 -
onreadystatechange- 设置"外卖送到后该做什么"的提醒 -
open()- 打开外卖APP,选择餐厅和菜品 -
send()- 点击"下单"按钮 -
回调函数 - 外卖小哥敲门时:
-
先确认是不是我的外卖(
readyState === 4) -
再检查外卖是否完好无损(
status检查) -
最后打开外卖开始享用(
console.log)
-
三:运行说明
要运行这段代码,你需要:
-
创建一个HTML文件
-
创建一个
text.json文件(包含一些JSON数据) -
通过web服务器访问(不能直接双击打开)
简单示例文件结构:
text
你的项目文件夹/ ├── index.html └── text.json
text.json 内容示例:
json
{
"name": "张三",
"age": 25,
"department": "技术部"
}
四:现代替换方案
fetch('text.json')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('错误:', error));
五:Ajax状态码
| Ajax状态码 | 状态 |
| 0 | (未初始化)未启动 |
| 1 | (启动)已经调用 open(),但尚未调用 send() |
| 2 | (发送)发送状态,已经调用 send(),但尚未接收到响应 |
| 3 | (接收)已经接收到部分响应数据 |
| 4 | (完成)已经接收到全部响应数据,而且已经可以在浏览器中使用了 |
六:跨域
什么是跨域?为什么会有跨域这种问题存在?
跨域的字面意思来说,就是向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域
https(协议)://a.xxx.***(域名):8080(端口号)/flie/list(路径)
只要协议、域名、端口号,只要有任何一个不一样,都是不同域
七:同源策略
同源策略限制了跨域,同源策略是浏览器核心的安全机制,如果没有了同源策略,浏览器的正常功能就会受到影响,所以web是构建在同源策略的基础之上。
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
以下就是不同源:
前端: http://a.***:8080/
服务端:https//b.***/api/xxx
所以同源就是协议、域名、 端口号都要一样。
跨域解决方法
1.CORS 跨域资源共享
2.JSONP
八:写一个简易的Ajax
function ajax(url) {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true)
xhr.onreadystatechange = () => {
if(xhr.readyState === 4){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
resolve(
JSON.parse(xhr.response)
)
}else{
reject(new Error('Response error'))
}
}
}
xhr.send(null)
})
return p
}
const url = 'text.json'
ajax(url).then(res => console.log(res)).catch(err => console.log(err))
这是一个 自定义的 AJAX 函数,用 Promise 包装了 XMLHttpRequest,让异步请求的处理更加优雅。
逐行详细解析
第1-16行:ajax 函数定义
javascript
function ajax(url) {
const p = new Promise((resolve, reject) => {
// 这里是 Promise 的执行器
})
return p
}
-
作用:创建一个返回 Promise 的 ajax 函数
-
resolve:成功时调用的函数
-
reject:失败时调用的函数
第3-14行:Promise 执行器
javascript
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true)
xhr.onreadystatechange = () => {
if(xhr.readyState === 4){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
resolve(JSON.parse(xhr.response)) // 成功!
}else{
reject(new Error('Response error')) // 失败!
}
}
}
xhr.send(null)
关键改进点:
第8行:resolve(JSON.parse(xhr.response))
-
之前的代码只是
console.log显示数据 -
现在用
resolve()把成功的结果"传递出去" -
JSON.parse()把 JSON 字符串转换成 JavaScript 对象
第10行:reject(new Error('Response error'))
-
如果请求失败,用
reject()传递错误信息 -
创建了一个 Error 对象,包含错误描述
第17-18行:使用 ajax 函数
javascript
const url = 'text.json'
ajax(url).then(res => console.log(res)).catch(err => console.log(err))
使用方式:
-
.then():处理成功情况-
res就是resolve()传递过来的数据(已经是 JavaScript 对象)
-
-
.catch():处理失败情况-
err就是reject()传递过来的错误信息
-
新旧版本对比
旧版本(回调方式):
javascript
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
// 各种条件判断...
console.log(xhr.responseText); // 只能在这里处理
};
xhr.open('GET', 'text.json', true);
xhr.send(null);
新版本(Promise 方式):
javascript
ajax('text.json')
.then(res => {
console.log(res); // 清晰的成功处理
// 还可以继续处理数据...
})
.catch(err => {
console.log(err); // 清晰的错误处理
});
比喻理解
把这两种方式比作点外卖:
旧版本(回调):
-
你站在门口一直等外卖
-
外卖到了直接在现场吃
-
如果外卖出了问题,也要在原地处理
新版本(Promise):
-
你点完外卖就可以去做别的事
-
外卖到了会 打电话通知你(
.then()) -
如果出问题了也会 打电话告诉你(
.catch()) -
你可以在任何方便的地方处理外卖
Promise 的优势
-
链式调用:可以连续处理多个异步操作
javascript
ajax('text.json')
.then(res => processData(res))
.then(processed => saveData(processed))
.then(() => console.log('所有操作完成'))
.catch(err => console.log('某个环节出错了'));
-
错误集中处理:一个
.catch()捕获所有错误 -
代码更清晰:成功和失败的逻辑分开,易于阅读和维护
完整工作流程
-
调用
ajax('text.json'),返回一个 Promise 对象 -
发送 HTTP 请求到服务器
-
如果成功:
-
服务器返回 JSON 数据
-
resolve(JSON.parse(xhr.response))被调用 -
.then()中的函数执行,接收到解析后的 JavaScript 对象
-
-
如果失败:
-
reject(new Error('Response error'))被调用 -
.catch()中的函数执行,接收到错误信息
-
这种封装让异步请求的代码更加现代化和易用,是现在前端开发中的常见做法!