Nodejs 求助:表单中文,request.setEncoding('utf8') 乱码

Nodejs 求助:表单中文,request.setEncoding(‘utf8’) 乱码

场景:前台一个简单的form 登陆页 提交姓名,汉字。用firebug观察post请求如下:

参数application/x-www-form-urlencoded
age	
name	王
源代码
name=%E7%8E%8B&age=

可见浏览器对汉字进行了UTF-8的URL编码。

后台nodejs服务器 代码:

 function queryName(response, request){
	var postData = "";
	request.setEncoding('utf8');
	request.addListener("data", function(postDataChunk){
		postData += postDataChunk;
		console.log("Received POST data chunk '"+postDataChunk+"'.");
	});
	request.addListener("end", function(){
		console.log("完成:"+params.name);
	});
}

request.setEncoding(‘utf8’);后依然是, name=%E7%8E%8B&age=

求真相。


7 回复

Node.js 求助:表单中文,request.setEncoding(‘utf8’) 乱码

场景描述

你有一个简单的前端登录表单,用户提交姓名(包含中文字符)。通过 Firebug 观察到 POST 请求如下:

参数: application/x-www-form-urlencoded
age	
name	王

源代码:
name=%E7%8E%8B&age=

可以看到浏览器对中文字符进行了 UTF-8 的 URL 编码。

后台 Node.js 代码

你在 Node.js 服务器端接收并处理这些数据,代码如下:

function queryName(response, request) {
    var postData = "";
    request.setEncoding('utf8'); // 设置解码为 utf8
    request.on("data", function (postDataChunk) {
        postData += postDataChunk;
        console.log("Received POST data chunk '" + postDataChunk + "'.");
    });
    request.on("end", function () {
        console.log("完成:" + params.name);
    });
}

问题描述

尽管设置了 request.setEncoding('utf8'),但你仍然收到的是编码后的字符串 name=%E7%8E%8B&age=,而不是解码后的中文字符。

解决方案

  1. 使用 querystring 模块解析 POST 数据 在 Node.js 中,你可以使用内置的 querystring 模块来解析 URL 编码的查询字符串。

    const querystring = require('querystring');
    
    function queryName(response, request) {
        let postData = '';
        request.setEncoding('utf8');
    
        request.on("data", function (postDataChunk) {
            postData += postDataChunk;
            console.log("Received POST data chunk '" + postDataChunk + "'.");
        });
    
        request.on("end", function () {
            const parsedData = querystring.parse(postData);
            console.log("完成:", parsedData.name);
        });
    }
    
  2. 确保 HTTP 请求头正确设置 确保你的 HTTP 请求头中 Content-Type 被设置为 application/x-www-form-urlencoded,这样 Node.js 才能正确解析 POST 数据。

    response.writeHead(200, { 'Content-Type': 'text/html' });
    
  3. 调试输出 添加一些调试输出,确保你能够看到正确的数据流。

    request.on("data", function (postDataChunk) {
        postData += postDataChunk;
        console.log("Received POST data chunk '" + postDataChunk + "'.");
    });
    
    request.on("end", function () {
        console.log("Complete POST data:", postData);
        const parsedData = querystring.parse(postData);
        console.log("完成:", parsedData.name);
    });
    

通过以上步骤,你应该能够正确解析并显示中文字符。关键在于使用 querystring 模块来解析 URL 编码的数据,并确保 HTTP 头信息正确设置。


前台用了它再试试,encodeURIComponent

<html>  
<head>  
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />  
</head>  
<body>  
    <form action="/queryName" method="post">  
        用户名:<input type="text" name="name"> </br> 
		年龄:<input type="text" name="age"></br>  
        <input type="submit" value="登录">  
    </form>  
</body></html>

仅仅是个表单提交啊,如何用得encodeURIComponent呢

目前的解决方案是 在后端 用

decodeURIComponent()

request.setEncoding('utf8')这是针对字节流对字符解码,UTF-8的URL编码是遵循x-www-form-urlencoded格式,两者有关系么。nodejs没对URL编码的内容自动解码,怎么都不可能怪到setEncoding的身上。

楼上分析的有道理,我试了一下正常的form表单提交,用firebug看发现汉字也都是进行了URL编码,可能是经过tomcat服务器时候进行了解码处理然后传到后台的。跟nodejs确实不一样。果然还得适应一下。谢谢各位指点,涨姿势了

根据你的描述,问题在于虽然你在 Node.js 中设置了 request.setEncoding('utf8'),但是 postDataChunk 仍然以 URL 编码的形式存在。你需要将 URL 编码的字符串解码为实际的 UTF-8 字符串。

解决方法

  1. 使用 querystring 模块解析 POST 数据。
  2. 将解码后的数据存储在 postData 变量中。

示例代码

const http = require('http');
const querystring = require('querystring');

function queryName(request, response) {
    let postData = '';
    
    request.setEncoding('utf8');
    request.on("data", (postDataChunk) => {
        postData += postDataChunk;
    });

    request.on("end", () => {
        const params = querystring.parse(postData);
        console.log("完成:", params.name);
        
        // 返回响应
        response.writeHead(200, { 'Content-Type': 'text/plain' });
        response.end(`Received: ${params.name}`);
    });
}

const server = http.createServer((req, res) => {
    if (req.method === 'POST' && req.url === '/login') {
        queryName(req, res);
    } else {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('Not Found');
    }
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 使用 querystring 模块:通过 querystring.parse(postData) 解析 URL 编码的数据。
  2. 设置编码:使用 request.setEncoding('utf8') 确保接收到的数据是 UTF-8 编码。
  3. 监听事件:分别处理 dataend 事件,累积数据并在请求结束时进行处理。

这样处理后,你应该能够正确地获取并显示表单中的中文字符。

回到顶部