Nodejs querystring模块处理post表单时候含有%百分号中文字符会出现乱码
Nodejs querystring模块处理post表单时候含有%百分号中文字符会出现乱码
如果使用querystring处理POST数据 如: content=中文%
那么得到的json中,中文会变成乱码
Node.js querystring 模块处理 POST 表单时含有 %
百分号中文字符会出现乱码
问题描述
在使用 Node.js 的 querystring
模块处理包含 %
百分号的中文字符的 POST 请求表单数据时,可能会出现乱码问题。例如,当表单数据包含 content=中文%
时,解析后的 JSON 中的中文字符可能显示为乱码。
原因分析
querystring
模块默认不会对 URL 编码的字符串进行解码。因此,如果表单数据中包含 URL 编码的字符(如 %E4%B8%AD%E6%96%87
),直接使用 querystring.parse()
解析后,这些字符仍然保持编码状态,导致乱码问题。
解决方案
为了解决这个问题,我们需要手动对解码后的字符串进行 URL 解码。可以使用 Node.js 的内置模块 decodeURIComponent
来实现这一点。
示例代码
以下是一个简单的示例,展示了如何处理这种情况:
const http = require('http');
const querystring = require('querystring');
http.createServer((req, res) => {
if (req.method === 'POST') {
let body = [];
req.on('data', chunk => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// 解析请求体
const parsedBody = querystring.parse(body);
// 对解析后的值进行 URL 解码
Object.keys(parsedBody).forEach(key => {
parsedBody[key] = decodeURIComponent(parsedBody[key]);
});
console.log(parsedBody);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(parsedBody));
});
} else {
res.writeHead(405, { 'Content-Type': 'text/plain' });
res.end('Only POST requests are supported.');
}
}).listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
- 创建 HTTP 服务器:我们使用
http.createServer
创建一个 HTTP 服务器。 - 监听 POST 请求:我们只处理 POST 请求。
- 读取请求体:我们将请求体中的数据存储在一个数组中,并在请求结束时将其合并成一个完整的字符串。
- 解析请求体:使用
querystring.parse()
解析请求体。 - URL 解码:遍历解析后的对象,并使用
decodeURIComponent()
对每个值进行解码。 - 返回结果:将解码后的对象以 JSON 格式返回给客户端。
通过这种方式,我们可以确保即使表单数据中包含 URL 编码的字符,也能正确地解析并显示中文字符。
貌似浏览器进行的转义, GET 请求明确是会对中文字符进行转义的, POST 具体不清楚, 求高人…
%百分号是 encodeURIComponent(“中文”) 之后出现的,如果你想 decodeURIComponent 之后还保留 %百分号,那么必须对百分号也进行encode,变成 %25,你上面就应该是 content = 中文%25
没有对POST进行encodeURIComponent,原来querystring会进行一次decodeURIComponent Thanks
楼上正解,querystring真不是个好模块。
当使用 Node.js 的 querystring
模块处理包含 %
百分号的中文字符时,可能会出现乱码问题。这是因为 querystring
模块默认将这些字符视为 URL 编码的一部分,而不是直接解析为实际的中文字符。
示例代码
假设有一个 POST 请求体,内容如下:
content=中文%
使用 querystring
模块处理时:
const http = require('http');
const querystring = require('querystring');
http.createServer((req, res) => {
if (req.method === 'POST') {
let body = [];
req.on('data', chunk => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
const parsedBody = querystring.parse(body);
console.log(parsedBody); // { content: '中文%' }
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(parsedBody));
});
} else {
res.writeHead(405, { 'Content-Type': 'text/plain' });
res.end('Method Not Allowed');
}
}).listen(3000, () => {
console.log('Server is running on port 3000');
});
解决方法
为了解决这个问题,你可以使用 decodeURIComponent
函数手动解码 content
字段:
const http = require('http');
const querystring = require('querystring');
http.createServer((req, res) => {
if (req.method === 'POST') {
let body = [];
req.on('data', chunk => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
const parsedBody = querystring.parse(body);
// 手动解码 content 字段
if (parsedBody.content) {
parsedBody.content = decodeURIComponent(parsedBody.content);
}
console.log(parsedBody); // { content: '中文%' }
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(parsedBody));
});
} else {
res.writeHead(405, { 'Content-Type': 'text/plain' });
res.end('Method Not Allowed');
}
}).listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
- 问题原因:
querystring
模块默认将%
视为 URL 编码的一部分,导致中文字符无法正确解析。 - 解决方法:使用
decodeURIComponent
函数手动解码content
字段,使其正确显示为中文字符。
通过这种方式,可以确保即使在 content
字段中含有 %
百分号的中文字符时,也能正确解析并显示。