JavaScript网络请求Ajax

百科知识2025-04-272

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;"); // 设置请求头

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>

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>

{
"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>

<meta charset="UTF-8">

在这个案例中,当用户点击登录按钮提交表单时,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特性来重构这段代码,使其扁平化并提高可读性与可维护性。

最后求点赞,求分享,求抱抱…