Nodejs querystring模块处理post表单时候含有%百分号中文字符会出现乱码

Nodejs querystring模块处理post表单时候含有%百分号中文字符会出现乱码

如果使用querystring处理POST数据 如: content=中文%

那么得到的json中,中文会变成乱码

6 回复

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');
});

解释

  1. 创建 HTTP 服务器:我们使用 http.createServer 创建一个 HTTP 服务器。
  2. 监听 POST 请求:我们只处理 POST 请求。
  3. 读取请求体:我们将请求体中的数据存储在一个数组中,并在请求结束时将其合并成一个完整的字符串。
  4. 解析请求体:使用 querystring.parse() 解析请求体。
  5. URL 解码:遍历解析后的对象,并使用 decodeURIComponent() 对每个值进行解码。
  6. 返回结果:将解码后的对象以 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');
});

解释

  1. 问题原因querystring 模块默认将 % 视为 URL 编码的一部分,导致中文字符无法正确解析。
  2. 解决方法:使用 decodeURIComponent 函数手动解码 content 字段,使其正确显示为中文字符。

通过这种方式,可以确保即使在 content 字段中含有 % 百分号的中文字符时,也能正确解析并显示。

回到顶部