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 字段中含有 % 百分号的中文字符时,也能正确解析并显示。
        
      
                    
                  
                    
