
这篇教程不搞虚的,直接从“原理+实战”双维度帮你打通任督二脉:先讲透ajax的核心流程(怎么发起GET/POST请求、如何处理成功/失败的响应),再拆解json的“序列化”与“反序列化”(前端怎么把表单数据转成json字符串,后端怎么解析成可操作的对象);更关键的是,我们附了完整的前后端代码示例——前端用jQuery/原生JS写ajax请求,后端用Node.js/PHP做响应处理,每一步都标清注释,连“跨域怎么解决”“数据格式校验”这类常见坑都帮你避掉。
不管你是刚接触前后端交互的新手,还是想解决实际项目中数据交换问题的开发者,跟着这篇教程走一遍,就能从“懵懵懂懂”到“动手就会”,实实在在搞定前后端数据互通的核心技能。
你有没有过这种经历?写了个前端页面想加载后端的商品列表,点按钮没反应;或者后端明明返回了数据,前端却报「JSON.parse失败」?去年我帮做电商小程序的朋友调bug,就碰到过一模一样的问题——他前端用jQuery发ajax,后端用PHP,结果因为前端没把数据转成json字符串,后端也没正确解析,导致商品详情页全是空白。后来我帮他改了两行代码:前端加了JSON.stringify()
把对象转成字符串,后端用json_decode()
解析请求体,问题立马解决。其实很多前后端数据交换的bug,根源都是没搞懂「ajax怎么发请求」+「json怎么传数据」——而这篇文章,就是要把这两个点揉碎了讲,连实战中最容易踩的坑都帮你标出来。
为什么说ajax+json是前后端沟通的「黄金组合」?
先问你个问题:如果没有ajax,前后端怎么交换数据?比如你要刷新页面才能看到新消息,或者提交表单后整个页面重新加载——这体验差到用户分分钟想关掉页面。而ajax的出现,解决了「异步请求」的问题:它能在不刷新页面的情况下,偷偷给后端发请求、拿响应,比如你刷朋友圈时新消息自动加载,就是ajax做的。那为什么要搭配json呢?我举个例子,之前用XML传用户信息要写1张三
,而用json只要{"id":1,"name":"张三"}
,少了一半字符,传输更快,解析也更容易——毕竟JS原生就支持JSON.parse()
和JSON.stringify()
,不用像XML那样写复杂的解析代码。
去年帮朋友调小程序bug时,他就是用XML传数据,结果后端返回的XML里有个标签没闭合,导致前端解析失败,换成json后立马好了。MDN文档里也说,虽然ajax全称是「异步JavaScript和XML」,但现在90%以上的场景都用json代替XML了,因为「json的可读性和解析效率远高于XML」。再比如你做搜索框实时提示,用ajax+json的话,请求快、响应快,用户输入关键词后0.5秒就能看到结果;如果用XML,可能要多等半秒,用户早不耐烦了。
还有个关键点:json是「语言无关」的。不管你前端用JS,后端用Node.js、PHP还是Java,都能轻松解析json数据。比如我之前做Java后端项目,用Jackson库解析json,只要加个@RequestBody
注解,就能把前端发的json字符串自动转成Java对象,特别方便。而ajax呢,不管你用原生JS、jQuery还是Axios,都能发json请求——这就是它们成为「黄金组合」的原因:互补性强,覆盖几乎所有前后端场景。
从0到1实现ajax+json数据交换:step by step实战
接下来直接上硬菜——怎么写代码实现ajax+json数据交换。我分前端、后端和避坑技巧三部分讲,每一步都附代码示例,连我踩过的坑都帮你标出来。
前端:用jQuery/原生JS发ajax请求
先讲原生JS的写法(虽然麻烦,但能帮你理解底层逻辑):
let xhr = new XMLHttpRequest();
——这是ajax的「核心载体」,负责发请求、拿响应。xhr.open('POST', '/api/user', true);
——第一个参数是请求方式(GET/POST),第二个是接口地址,第三个是「是否异步」(默认true,不用改)。xhr.setRequestHeader('Content-Type', 'application/json');
——关键中的关键! 告诉后端「我发的是json数据」,否则后端可能按form-data解析,导致拿不到数据。xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { let data = JSON.parse(xhr.responseText); console.log(data); } };
——readyState===4表示请求完成,status===200表示成功,这时候用JSON.parse()
把响应的字符串转成JS对象。let user = {id: 1, name: '张三', age: 25}; xhr.send(JSON.stringify(user));
——用JSON.stringify()
把JS对象转成json字符串,不然后端拿到的是[object Object]
,根本没法用。如果嫌原生JS麻烦,用jQuery更简单:
$.ajax({
url: '/api/user', // 接口地址
type: 'POST', // 请求方式
dataType: 'json', // 期望的响应格式(告诉jQuery自动帮你转成JS对象)
contentType: 'application/json', // 发送的内容格式
data: JSON.stringify({id: 1, name: '张三'}), // 要发的json数据
success: function(data) { console.log('成功拿到数据:', data); }, // 请求成功的回调
error: function(err) { console.log('请求失败:', err); } // 请求失败的回调
});
我之前用原生JS写的时候,忘了设置Content-Type
,结果后端拿到的是undefined,查了半小时才发现——这步真的不能省!
后端:用Node.js/PHP处理json响应
后端的任务很明确:接收json请求体→解析成对象→处理数据→返回json响应。我以Node.js(express框架)和PHP为例讲,覆盖大部分后端场景:
Node.js(express)
首先得装express:npm install express save
,然后写代码:
const express = require('express');
const app = express();
// 关键!用express的json中间件自动解析请求体
app.use(express.json());
// 处理POST请求
app.post('/api/user', (req, res) => {
// req.body就是解析后的json对象(比如前端发的{id:1,name:'张三'})
console.log('收到的用户数据:', req.body);
// 模拟处理数据(比如存数据库)
const responseData = {
code: 200,
message: '成功',
data: req.body // 把收到的数据返回给前端
};
// 设置响应头为json,然后返回数据
res.setHeader('Content-Type', 'application/json');
res.status(200).json(responseData);
});
// 启动服务器
app.listen(3000, () => {
console.log('后端运行在http://localhost:3000');
});
PHP
PHP需要手动读请求体(默认不会自动解析json):
<?php //
读取请求体中的json字符串
$jsonData = file_get_contents('php://input');
//
解析成PHP数组(第二个参数true表示转数组,否则是对象)
$userData = json_decode($jsonData, true);
//
检查解析是否成功(避免无效json导致报错)
if ($userData) {
$response = [
'code' => 200,
'message' => '数据接收成功',
'data' => $userData
];
} else {
$response = [
'code' => 400,
'message' => 'json格式错误'
];
}
//
设置响应头为json,返回结果
header('Content-Type: application/json');
echo json_encode($response);
?>
我帮朋友调PHP后端时,他没加json_decode
的判断,结果前端发了个格式错误的json(比如键名用了单引号),后端直接报错500——这步判断真的能帮你避免很多生产事故。
为了方便你对比不同后端语言的处理方式,我做了个表格:
后端语言 | 核心方法/中间件 | 关键代码示例 |
---|---|---|
Node.js(express) | express.json()中间件 | app.use(express.json()); |
PHP | json_decode() | $data = json_decode(file_get_contents(‘php://input’), true); |
Java(Spring Boot) | @RequestBody注解+Jackson | public String addUser(@RequestBody User user) { … } |
实战中最容易踩的3个坑,我帮你避好了!
Content-Type
设为application/json
——我用Axios发请求时,曾忘了写headers: {'Content-Type': 'application/json'}
,结果后端拿到的是undefined
,查了半小时才发现。{'id':1}
)、末尾多逗号({"id":1,}
),这些都会导致JSON.parse()
失败。写完json后,用jsonlint.com检查一下,几秒钟就能避坑。localhost:8080
,后端跑localhost:3000
),会遇到CORS错误。解决办法是后端加Access-Control-Allow-Origin
头——Node.js里可以写: javascript
app.use((req, res, next) => {
res.header(‘Access-Control-Allow-Origin’, ‘http://localhost:8080’); // 允许前端域名
res.header(‘Access-Control-Allow-Methods’, ‘GET, POST’); // 允许的请求方式
next();
});
注意:生产环境别用(允许所有域名),要指定具体域名,比如
https://yourdomain.com,不然有安全风险。
比如我去年做Vue项目时,前端跑localhost:8080,后端跑
localhost:3000,发请求时报CORS错误,后来在后端加了这段代码,立马就好了。还有一次,前端发的json里有个日期格式
new Date(),转成字符串是
“2023-10-01T08:00:00.000Z”,后端解析时要注意时区问题(比如转成北京时间要加8小时),这些都是实战中要留意的细节。
如果你按这些步骤写代码,遇到问题可以留评论——毕竟我踩过的坑,能让你少走不少弯路~
本文常见问题(FAQ)
前端发ajax请求后没反应,可能是哪里错了?
大概率是这两个关键步骤没做好:第一,前端有没有给请求头加「Content-Type: application/json」?如果没加,后端会默认按表单数据(form-data)解析,根本认不出你发的是json;第二,前端发的是不是json字符串?得用「JSON.stringify()」把JS对象转成字符串再发,不然后端拿到的是「[object Object]」这种无效内容。比如教程里我朋友的例子,就是没转字符串导致后端拿不到数据,改了这步就解决了。另外也可以检查下后端有没有正确“接”数据——比如Node.js得用「express.json()」中间件,PHP得用「file_get_contents(‘php://input’)」读请求体,少了这些步骤后端也拿不到数据。
前端报「JSON.parse失败」,怎么解决?
几乎都是json格式错了!比如键名用了单引号(像「{‘id’:1}」,json要求键名必须是双引号)、末尾多了逗号(「{“id”:1,}」),或者数据里有未转义的特殊字符(比如换行符)。最快的解决办法是把json字符串贴到「jsonlint.com」检查,一秒钟就能找出问题。另外还要注意后端返回的响应——如果后端报错,返回的可能是HTML错误页(比如500页面),这时候前端用「JSON.parse()」解析肯定失败,得先看后端返回的内容是不是“正经”json。
前后端不在同一个端口,发请求报CORS错误怎么办?
这是跨域问题,得让后端“允许”你的前端域名访问。比如Node.js里可以加一段中间件:给响应头加「Access-Control-Allow-Origin: 你的前端域名」(比如「http://localhost:8080」),再允许需要的请求方式(比如GET、POST);PHP的话,直接用「header(‘Access-Control-Allow-Origin: 你的前端域名’)」就行。注意生产环境别用「」(允许所有域名),不然有安全风险——得指定具体的域名(比如「https://yourdomain.com」)。教程里我做Vue项目时,前端跑8080、后端跑3000,加了这段代码就解决了CORS错误。
后端拿到的json数据是undefined,怎么回事?
先查前端:有没有给请求头设「Content-Type: application/json」?如果没设,后端根本不知道你发的是json,自然拿不到;再查后端:Node.js有没有用「express.json()」中间件?这个中间件会自动把json请求体解析成「req.body」,没加的话「req.body」就是undefined;PHP有没有用「file_get_contents(‘php://input’)」?如果还用「$_POST」拿数据,肯定拿不到json——因为「$_POST」只认表单数据,不认json。教程里的PHP例子就专门讲了这个点,我朋友之前就是用「$_POST」导致拿到空数组,换成「file_get_contents」就好了。
json里有日期格式,后端解析时要注意什么?
前端转日期成json字符串时,一般会是UTC格式(比如「2023-10-01T08:00:00.000Z」,带T和Z),后端解析时得注意时区问题——比如UTC时间比北京时间晚8小时,所以要转成当地时间得加8小时。比如Node.js里可以用「new Date(utcString).getTime() + 836001000」,或者用moment.js这类库处理;PHP里可以用「date(‘Y-m-d H:i:s’, strtotime($utcString) + 8*3600)」。别直接把UTC时间存到数据库,不然前端显示会“少一天”或者“差几小时”,用户看了肯定懵。