JavaScript 权威指南:与服务器通信,发送 JSON 数据的两种核心方法
在现代 Web 应用中,前端页面(客户端)动态地向后端服务器发送数据并接收响应,是实现一切复杂功能的基础。无论是用户注册、提交评论,还是保存应用状态,其核心都是将 JavaScript 对象包装成 JSON 格式,通过 HTTP 请求发送给服务器。
本篇权威指南将引导您从零开始,构建一个完整的“数据发送与回显”迷你项目。我们将:
- 搭建一个极简的 Node.js 服务器:作为我们数据的“接收方”。
- 构建一个前端表单页面:作为数据的“发送方”。
- 深入剖析并对比两种关键技术:
- Fetch API:现代、基于 Promise 的标准方法。
- XMLHttpRequest (XHR):经典、但已显陈旧的传统方法。
通过这个实战项目,您将彻底掌握客户端与服务器进行 JSON 数据交换的完整流程和最佳实践。
核心代码速览 (TL;DR)
对于希望快速获取现代最佳实践的开发者,以下是使用 async/await 和 Fetch API 发送 POST 请求的标准模式。
方法:使用 Fetch API 发送 JSON 数据
/**
* 向指定 URL 发送 JSON 数据的异步函数。
* @param {string} url - 目标服务器端点。
* @param {object} data - 要发送的 JavaScript 对象。
* @returns {Promise
async function postJson(url = '', data = {}) {
try {
const response = await fetch(url, {
method: 'POST', // 指定请求方法为 POST
headers: {
// 关键头部,告知服务器我们发送的是 JSON 格式的数据
'Content-Type': 'application/json',
},
// 将 JavaScript 对象转换为 JSON 字符串
body: JSON.stringify(data),
});
// 检查响应是否成功
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 解析并返回 JSON 响应
return await response.json();
} catch (error) {
console.error('Error during fetch operation:', error);
throw error;
}
}
// 示例用法:
const userData = { name: 'Alice', email: 'alice@example.com' };
postJson('/api/users', userData)
.then(responseData => {
console.log('Success:', responseData);
})
.catch(error => {
console.error('Failure:', error);
});
前置知识
- HTML/CSS 基础:了解
,,。 - JavaScript 基础:熟悉 DOM 操作、事件监听,并对 Promise 和
async/await有基本了解。 - 环境准备:本地安装了 Node.js 和 npm (用于搭建我们的迷你服务器)。
目录
- 项目概览与目标
- 第一部分:搭建“接收方”——一个极简 Node.js/Express 服务器
- 第二部分:构建“发送方”——前端 HTML 与 CSS
- 第三部分:实现数据发送的 JavaScript 逻辑
- 4.1 现代方法:使用
FetchAPI (推荐) - 4.2 传统方法:使用
XMLHttpRequest(了解历史)
- 4.1 现代方法:使用
- 深入探讨
- 5.1 关键概念:
JSON.stringify与Content-Type - 5.2 跨域问题 (CORS) 简介
- 5.1 关键概念:
- 总结
1. 项目概览与目标
我们将构建一个包含两部分的迷你应用:
- 一个运行在
http://localhost:3000的 Node.js 服务器,它有一个 API 端点,能够接收 JSON 数据并返回一个确认信息。 - 一个运行在本地文件系统的 HTML 页面,用户可以在页面上填写信息,点击按钮后,数据将被发送到上述服务器,并将服务器的响应显示在页面上。
2. 第一部分:搭建“接收方”——一个极简 Node.js/Express 服务器
没有服务器,前端的数据发送将“无的放矢”。让我们用几行代码快速搭建一个。
-
初始化项目:
在你的电脑上创建一个新文件夹(例如json-sender-project),进入该文件夹,在终端中运行:npm init -y npm install express cors这会初始化一个 Node.js 项目,并安装
express(一个流行的 web 框架)和cors(用于处理跨域问题)。 -
创建服务器代码 (
server.js):
在项目文件夹中创建一个名为server.js的文件,并填入以下内容:const express = require('express'); const cors = require('cors'); const app = express(); const PORT = 3000; // --- 中间件 --- app.use(cors()); // 允许所有来源的跨域请求 app.use(express.json()); // 关键!解析 application/json 格式的请求体 // --- 路由 --- app.post('/api/users', (req, res) => { console.log('收到客户端发送的数据:'); console.log(req.body); // req.body 包含了客户端发送的 JSON 对象 // 简单验证 if (!req.body.name || !req.body.email) { return res.status(400).json({ message: '错误:姓名和邮箱不能为空!' }); } // 发送成功响应 res.status(201).json({ message: `服务器已成功接收到用户 ${req.body.name} 的数据!`, data: req.body }); }); // --- 启动服务器 --- app.listen(PORT, () => { console.log(`服务器正在 http://localhost:${PORT} 上运行`); }); -
启动服务器:
在终端中运行node server.js。现在,你的数据接收方已经准备就绪!
3. 第二部分:构建“发送方”——前端 HTML 与 CSS
现在创建我们的前端页面。
HTML 代码 (index.html)
DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JSON 数据发送器title>
head>
<body>
<div class="container">
<h1>向服务器发送 JSON 数据h1>
<form id="user-form">
<div class="form-group">
<label for="name">姓名:label>
<input type="text" id="name" required value="Alice">
div>
<div class="form-group">
<label for="email">邮箱:label>
<input type="email" id="email" required value="alice@example.com">
div>
<button type="submit" class="btn">使用 Fetch 发送button>
form>
<div id="response-area" class="response-area">
<h2>服务器响应:h2>
<pre id="response-pre">pre>
div>
div>
body>
html>
CSS 代码 (style.css)
(此处省略基础的 CSS 代码,您可以根据自己的喜好设计表单和容器样式,确保界面清晰即可。)
4. 第三部分:实现数据发送的 JavaScript 逻辑
这是连接前端与后端的桥梁。
4.1 现代方法:使用 Fetch API (推荐)
Fetch 是现代浏览器内置的、基于 Promise 的 HTTP 请求接口,语法简洁且功能强大。
JavaScript 代码 (script.js)
const form = document.getElementById('user-form');
const responsePre = document.getElementById('response-pre');
const SERVER_URL = 'http://localhost:3000/api/users';
form.addEventListener('submit', async (event) => {
event.preventDefault(); // 阻止表单默认的提交行为
const name = document.getElementById('name').value;
const email = document.getElementById('email').value;
const userData = { name, email };
responsePre.textContent = '正在发送数据...';
try {
const response = await fetch(SERVER_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
const responseData = await response.json();
if (!response.ok) {
// 如果服务器返回错误状态 (如 400, 500)
throw new Error(responseData.message || `HTTP error! status: ${response.status}`);
}
responsePre.textContent = JSON.stringify(responseData, null, 2);
responsePre.style.color = '#2ecc71';
} catch (error) {
responsePre.textContent = `请求失败: ${error.message}`;
responsePre.style.color = '#e74c3c';
}
});
4.2 传统方法:使用 XMLHttpRequest (了解历史)
在 Fetch 出现之前,XMLHttpRequest (XHR) 是实现 AJAX 的唯一方式。它的语法更繁琐,基于事件回调。
// 使用 XHR 的等效实现
function sendWithXHR(userData) {
const xhr = new XMLHttpRequest();
xhr.open('POST', SERVER_URL, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
responsePre.textContent = JSON.stringify(JSON.parse(xhr.responseText), null, 2);
responsePre.style.color = '#2ecc71';
} else {
responsePre.textContent = `请求失败: ${xhr.statusText}`;
responsePre.style.color = '#e74c3c';
}
};
xhr.onerror = function() {
responsePre.textContent = '网络错误。';
responsePre.style.color = '#e74c3c';
};
xhr.send(JSON.stringify(userData));
}
// 在表单事件监听器中调用 sendWithXHR(userData);
通过对比可以明显看出,Fetch 和 async/await 的组合在代码结构、错误处理和可读性上都远胜于 XHR。
5. 深入探讨
5.1 关键概念:JSON.stringify 与 Content-Type
JSON.stringify(): HTTP 请求体 (body) 只能是字符串或二进制数据。我们不能直接发送一个 JavaScript 对象。JSON.stringify()的作用就是将 JavaScript 对象序列化为一个 JSON 格式的字符串,使其能够通过网络传输。Content-Type: application/json: 这个 HTTP 头部至关重要。它就像是给包裹贴上的“内容标签”,告诉服务器:“我发送给你的请求体是一段 JSON 格式的字符串,请用 JSON 解析器来处理它”。我们的 Express 服务器正是因为看到了这个头部,才启用了express.json()中间件来正确地解析请求体,并将其放入req.body。
5.2 跨域问题 (CORS) 简介
出于安全原因,浏览器默认实行“同源策略”,禁止一个源(例如 file:/// 或 http://localhost:8080)的脚本向另一个源(例如 http://localhost:3000)发起 HTTP 请求。
为了允许这种跨源通信,服务器必须在响应中包含特定的 HTTP 头部。这就是 CORS (Cross-Origin Resource Sharing) 机制。在我们的服务器代码中,app.use(cors()) 这行代码就是让 express 自动为所有响应添加必要的 CORS 头部,从而“授权”我们的前端页面可以访问它的 API。
6. 总结
通过这个完整的实战项目,我们掌握了现代 Web 开发中数据通信的核心流程:
- 准备数据:在前端将数据整理成一个 JavaScript 对象。
- 序列化与声明:使用
JSON.stringify()将对象转为字符串,并设置Content-Type: application/json头部。 - 发送请求:强烈推荐使用
FetchAPI 发起POST请求。 - 服务器处理:服务器端使用相应的中间件(如
express.json())来解析 JSON 数据。 - 处理响应:前端接收服务器的响应,解析 JSON 结果,并更新 UI。
理解并熟练运用这一流程,是构建任何动态、数据驱动的 Web 应用的基石。
本文地址:https://www.yitenyun.com/2328.html






