JavaScript的Ajax(Asynchronous JavaScript and XML)是一种在后台与服务器进行异步通信的技术,能够通过JavaScript在不刷新整个页面的情况下向服务器发送请求并获取响应。
使用Ajax可以实现以下功能:
动态更新页面内容:通过向服务器发送异步请求,可以在不刷新整个页面的情况下更新特定部分的内容。这可以提高用户体验并减少数据传输量。
异步加载数据:通过Ajax,可以在页面加载时异步加载数据,而不是等待整个页面加载完成。这样可以加快页面加载速度,并提高用户体验。
提交表单数据:通过Ajax,可以在不刷新整个页面的情况下将表单数据发送到服务器进行处理。这样可以实现即时验证和提交,并减少页面刷新的次数。
实时数据更新:通过使用Ajax轮询或长轮询技术,可以实现实时更新数据的功能,如聊天室、即时通讯等。
在JavaScript中,可以使用XMLHttpRequest对象来实现Ajax请求。XMLHttpRequest提供了向服务器发送请求和处理响应的方法和属性。以下是一个简单的示例:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
};
xhr.send();
在上面的示例中,我们创建了一个XMLHttpRequest对象,并使用open方法指定了请求的URL和请求方法(GET)。然后,我们使用onreadystatechange事件处理程序来监听请求状态的变化。当readyState为4(请求已完成)且status为200(成功)时,我们通过responseText属性获取服务器的响应内容,并将其解析为JSON格式。
除了使用GET方法,还可以使用POST方法发送数据到服务器。以下是一个使用POST方法发送表单数据的示例:
var xhr = new XMLHttpRequest();
var formData = new FormData();
formData.append('username', 'myUsername');
formData.append('password', 'myPassword');
xhr.open('POST', '/login', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
};
xhr.send(formData);
在上面的示例中,我们创建了一个FormData对象,并使用append方法添加了要发送的表单数据。然后,我们使用open方法指定了请求的URL和请求方法(POST)。最后,通过send方法发送请求,并将FormData对象作为参数传递给send方法。
使用Ajax可以大大提升网页的交互性和用户体验,并且可以实现实时更新数据、动态加载内容和提交表单等功能。
1-ajax案例
当然,我可以为您举一个简单的AJAX异步请求的例子。以下是一个使用原生JavaScript实现的AJAX GET请求案例,用于从服务器获取JSON数据:
// 创建一个新的XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 配置请求信息
xhr.open('GET', '/data/123', true); // 第三个参数为true表示异步请求
// 设置请求完成后的回调函数
xhr.onload = function() {
if (xhr.status === 200) { // HTTP状态码200表示成功
var data = JSON.parse(xhr.responseText); // 解析返回的JSON字符串为JavaScript对象
console.log(data); // 在控制台打印出响应的数据
// 这里可以进一步操作获取到的数据,例如更新页面内容
document.getElementById('result').innerHTML = data.title;
} else {
console.error('请求失败:' + xhr.status);
}
};
// 发送请求
xhr.send();
// 错误处理
xhr.onerror = function() {
console.error('发生网络错误');
};
在这个例子中,我们创建了一个AJAX请求来访问/data/123
这个API端点,并在请求成功时处理返回的JSON数据。如果HTTP状态码是200(表示请求成功),则将返回的数据解析为JSON并展示在页面上具有ID为’result’的元素中。同时,我们也设置了错误处理函数以应对可能出现的网络错误。
请注意,在现代JavaScript开发中,通常会使用Fetch API或者jQuery、axios等库来简化AJAX请求的编写。以下是使用Fetch API的一个相似例子:
fetch('/data/123')
.then(response => response.json()) // 将响应体转换为JSON
.then(data => {
console.log(data);
document.getElementById('result').innerHTML = data.title;
})
.catch(error => {
console.error('请求失败:', error);
});
2-ajax同步异步
在jQuery的Ajax请求中,同步和异步请求的区别主要在于是否阻塞浏览器的后续代码执行。下面分别给出同步(synchronous)和异步(asynchronous)请求的例子:
同步请求例子
$.ajax({
url: "/api/sync-data",
type: "GET",
async: false, // 设置为false表示进行同步请求
dataType: "json",
});
// 在同步请求下,直到服务器响应完成,以下代码才会被执行
console.log("这段代码会在Ajax请求完成后执行");
**注意:**现代浏览器通常不推荐使用同步Ajax请求,因为它会导致浏览器锁定,直至请求完成,用户体验极差,而且大部分现代浏览器已默认不允许在主线程上执行同步Ajax请求。
异步请求例子
这是更常见的用法:
$.ajax({
url: "/api/async-data",
type: "GET",
dataType: "json",
success: function(response) {
console.log("收到服务器数据:", response);
// 这段代码在服务器返回响应后异步执行
},
error: function(xhr, status, error) {
console.error("请求失败:", status, error);
},
});
console.log("这段代码会立即执行,不会等待Ajax请求完成");
在异步请求中,success
、done
或 then
回调函数将在服务器响应就绪后异步执行,而不会阻塞后续的JavaScript代码。这意味着Ajax请求发出后,紧跟其后的代码会立即执行,不受服务器响应时间的影响。
3-请求方式-1
在HTTP协议中,常见的请求方式主要有GET、POST、PUT、DELETE等。这里分别给出一个使用jQuery的GET请求的例子:
GET请求例子
$.ajax({
url: "/api/data",
type: "GET", // 使用GET方法请求数据
dataType: "json",
success: function(response) {
console.log("获取的数据:", response);
},
error: function(xhr, status, error) {
console.error("GET请求失败:", status, error);
},
});
4-请求方式-2
如果您是指其他的HTTP请求方式,例如POST,请看下面的例子:
// 使用原生XMLHttpRequest实现POST请求
var xhr = new XMLHttpRequest();
xhr.open('POST', '/data', true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); // 设置请求头
xhr.onload = function() {
if (xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
console.log(data);
} else {
console.error('请求失败:' + xhr.status);
}
};
xhr.onerror = function() {
console.error('发生网络错误');
};
var data = { key1: 'value1', key2: 'value2' }; // 要发送的数据
xhr.send(JSON.stringify(data));
在这个POST请求示例中,我们不仅设置了请求方式为POST,还设置了请求头Content-Type表明发送的数据格式为JSON,并使用send方法发送了一个JSON对象。
5-ajax封装-1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./"></script>
<script>
// ajax({
// url:"http://localhost:3000/users",
// data:{
// username:"kerwin222",
// password:"789"
// },
// success:function(res){
// ("sucess",res)
// },
// error:function(err){
// ("error",err)
// }
// })
ajax({
url:"http://localhost:3000/users",
method:"POST",
data:{
username:"kerwin3333",
password:"789"
},
headers:{
"content-type":"application/json"
},
success:function(res){
console.log("sucess",res)
},
error:function(err){
console.log("error",err)
}
})
</script>
</body>
</html>
{
"users": [
{
"username": "ximen",
"password": "789",
"id": 5
},
{
"username": "kuo",
"password": "789",
"id": 6
},
{
"username": "kuo",
"password": "789",
"id": 7
},
{
"username": "kuo",
"password": "789",
"id": 8
},
{
"username": "kuo",
"password": "789",
"id": 9
},
{
"username": "kuo",
"password": "789",
"id": 10
},
{
"username": "kuo",
"password": "789",
"id": 11
},
{
"username": "kuo",
"password": "789",
"id": 12
},
{
"username": "kuo",
"password": "789",
"id": 13
},
{
"username": "kuo",
"password": "789",
"id": 14
},
{
"username": "kuo",
"password": "789",
"id": 15
},
{
"username": "kuo",
"password": "789",
"id": 16
},
{
"username": "kuo",
"password": "789",
"id": 17
},
{
"username": "kuo",
"password": "789",
"id": 18
},
{
"username": "kuo",
"password": "789",
"id": 19
},
{
"username": "kuo",
"password": "789",
"id": 20
},
{
"username": "kuo",
"password": "789",
"id": 21
},
{
"username": "kuo",
"password": "789",
"id": 22
},
{
"username": "kuo",
"password": "789",
"id": 23
},
{
"username": "kuo",
"password": "789",
"id": 24
},
{
"username": "kuo",
"password": "789",
"id": 25
},
{
"username": "kuo",
"password": "789",
"id": 26
},
{
"username": "kuo1",
"password": "789",
"id": 27
},
{
"username": "kuo1",
"password": "789",
"id": 28
},
{
"username": "kuo1",
"password": "789",
"id": 29
},
{
"username": "kuo1",
"password": "789",
"id": 30
},
{
"username": "kuo1",
"password": "789",
"id": 31
},
{
"username": "kuo1",
"password": "789",
"id": 32
},
{
"username": "kuo1",
"password": "789",
"id": 33
},
{
"username": "kuo1",
"password": "789",
"id": 34
}
],
"list": [
"1111",
"2222",
"3333"
]
}
function queryStringify(obj) {
let str = ''
for (let k in obj) str += `${k}=${obj[k]}&`
//username=kerwin&password=789&
return str.slice(0, -1)
}
// 封装 ajax
function ajax(options) {
let defaultoptions = {
url: "",
method: "GET",
async: true,
data: {},
headers: {},
success: function () { },
error: function () { }
}
let { url, method, async, data, headers, success, error } = {
...defaultoptions,
...options
}
// (url, method, async, data, headers, success, error)
if (typeof data === 'object' && headers["content-type"]?.indexOf("json") > -1) {
data = JSON.stringify(data)
}
else {
data = queryStringify(data)
}
// // 如果是 get 请求, 并且有参数, 那么直接组装一下 url 信息
if (/^get$/i.test(method) && data) url += '?' + data
// // 4. 发送请求
const xhr = new XMLHttpRequest()
xhr.open(method, url, async)
xhr.onload = function () {
if (!/^2\d{2}$/.test(xhr.status)) {
// (error)
error(`错误状态码:${xhr.status}`) //回调
return
}
// 执行解析
try {
let result = JSON.parse(xhr.responseText)
success(result)
} catch (err) {
error('解析失败 ! 因为后端返回的结果不是 json 格式字符串')
}
}
// (22222)
// // 设置请求头内的信息
for (let k in headers) xhr.setRequestHeader(k, headers[k])
if (/^get$/i.test(method)) {
xhr.send()
} else {
xhr.send(data)
}
// (data)
}
6-ajax封装-2
以下是一个使用原生JavaScript封装的简单Ajax函数示例,它支持GET和POST请求:
// 简单的AJAX封装函数
function ajaxRequest(method, url, data = null, callbackSuccess, callbackError) {
var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
xhr.onreadystatechange = function() { // 设置状态改变时的回调函数
if (xhr.readyState === 4) { // 成功完成请求(请求已发送、接收数据完毕)
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) { // HTTP状态码正常
try {
var response = JSON.parse(xhr.responseText); // 如果返回的是JSON,则解析为JS对象
callbackSuccess(response);
} catch (e) {
callbackSuccess(xhr.responseText); // 非JSON格式直接返回原始响应文本
}
} else {
callbackError(xhr.status, xhr.statusText); // 请求失败时调用错误回调
}
}
};
// 根据HTTP方法设置请求
if (method === 'POST') {
xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // POST请求一般设置内容类型
xhr.send(encodeFormData(data)); // 对POST数据进行URL编码后发送
} else if (method === 'GET') {
xhr.open('GET', url + '?' + encodeFormData(data), true); // GET请求将数据附加在URL后面
xhr.send();
}
// 辅助函数:对数据进行URL编码
function encodeFormData(data) {
return Object.keys(data).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`).join('&');
}
}
// 使用封装好的ajax函数的例子:
var requestData = { id: 123, name: 'John Doe' };
ajaxRequest('GET', '/api/data', requestData, function(response) {
console.log('成功获取数据:', response);
}, function(status, statusText) {
console.error(`请求失败,状态码:${status},错误信息:${statusText}`);
});
// POST请求例子
ajaxRequest('POST', '/api/submit', requestData, function(response) {
console.log('数据提交成功,服务器响应:', response);
}, function(status, statusText) {
console.error(`数据提交失败,状态码:${status},错误信息:${statusText}`);
});
这个函数接受5个参数:
-
method
:HTTP请求方法,如’GET’或’POST’ -
url
:请求的URL -
data
:要发送的数据(对于GET是查询字符串形式,对于POST则是键值对) -
callbackSuccess
:请求成功后的回调函数,处理服务器返回的数据 -
callbackError
:请求失败后的回调函数,处理错误信息
注意:实际开发中,为了兼容现代浏览器以及更好地处理各种情况,可能需要更复杂的封装,例如支持其他HTTP方法、设置超时、预处理请求头等。
7-ajax前后端交互案例
当然,这里是一个使用jQuery库进行Ajax前后端交互的POST请求示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="/jquery-3.6."></script>
</head>
<body>
<!-- 假设有一个表单 -->
<form id="myForm">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
<div id="response"></div>
<script>
$(document).ready(function() {
// 为表单绑定提交事件
$("#myForm").submit(function(event) {
event.preventDefault(); // 阻止表单默认提交行为
var formData = $(this).serialize(); // 序列化表单数据
$.ajax({
type: "POST", // 请求类型为POST
url: "/api/login", // 后端处理登录请求的URL
data: formData, // 发送给后端的数据
dataType: "json", // 指定服务器响应的数据类型(这里假设是JSON)
success: function(response) { // 请求成功时的回调函数
if (response.status === 'success') {
$("#response").html("登录成功!"); // 在页面上显示成功的提示信息
// 这里可以进一步执行登录成功的操作,如跳转到主页等
} else {
$("#response").html("登录失败:" + response.message); // 显示错误信息
}
},
error: function(xhr, status, error) { // 请求失败时的回调函数
$("#response").html("请求出错:" + error);
}
});
});
});
</script>
</body>
</html>
在这个案例中,当用户点击登录按钮提交表单时,AJAX会发送一个POST请求到 /api/login
这个后端接口,并携带表单中的用户名和密码数据。后端接收到请求并验证用户身份后,会返回一个JSON格式的响应。前端根据响应的状态来更新页面内容,显示登录结果或错误信息。
8-回调地狱问题
回调地狱问题在JavaScript中常见于异步编程,特别是在环境和早期的前端Ajax请求处理中。以下是一个使用纯回调函数实现的文件读取操作的例子,展示了回调地狱的情况:
const fs = require('fs'); // 假设这是环境下的文件系统模块
// 回调地狱例子:
fs.readFile('', 'utf8', function(err, data1) {
if (err) {
console.error('Error reading file1:', err);
return;
}
console.log('File1 contents:', data1);
fs.readFile('', 'utf8', function(err, data2) {
if (err) {
console.error('Error reading file2:', err);
return;
}
console.log('File2 contents:', data2);
fs.readFile('', 'utf8', function(err, data3) {
if (err) {
console.error('Error reading file3:', err);
return;
}
console.log('File3 contents:', data3);
// 进行下一步需要基于data1、data2和data3的操作...
});
});
});
在这个例子中,我们有三个连续的调用,每个调用都依赖于前一个调用的结果。这种嵌套的回调函数结构导致代码变得非常难以阅读和维护,尤其是在需要处理更多层级异步操作时,这就是所谓的“回调地狱”。
为了解决这个问题,可以采用Promise、async/await等现代JavaScript特性来重构这段代码,使其扁平化并提高可读性与可维护性。
最后求点赞,求分享,求抱抱…