You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js控制器无法保存UTF-8编码的阿拉伯语尺寸名称

问题描述

Node.js控制器无法以UTF-8编码保存阿拉伯语尺寸名称,但其余阿拉伯语数据可正常发送至服务器。控制台打印尺寸名称显示正常;提交表单后阿拉伯语字符变为乱码。表单已指定accept-charset="UTF-8",接收的数据打印也正常。

排查与解决方案

1. 修正代码逻辑错误

从提供的代码看,newItem初始化及文件写入逻辑位于upload.single('image')回调函数外部,这会导致变量未定义且执行顺序错误。必须将这部分代码移至upload回调内部,确保文件上传和表单数据解析完成后再执行保存操作。

2. 确保Multer正确解析UTF-8字段名

当表单包含非ASCII字符的字段名(如阿拉伯语尺寸名称)时,需显式配置Multer支持UTF-8编码解析:

const upload = multer({
  storage: 你的存储配置,
  limits: {
    fieldNameSize: 255 // 确保字段名长度足够容纳阿拉伯语字符
  }
});

3. 手动解码字段名(可选)

如果Multer仍未正确解析阿拉伯语字段名,可在遍历sizePrice时手动解码:

Object.keys(sizePrice).forEach(encodedSizeName => {
  const sizeName = decodeURIComponent(encodedSizeName);
  // 后续处理逻辑
});

4. 验证JSON序列化与文件编码

虽然已在fs.writeFile中指定utf8编码,仍需确保:

  • JSON.stringify生成的内容不会被错误转义(默认转义为Unicode序列是合法的,读取时会自动解析);
  • 读取文件时始终指定utf8编码。
修正后的控制器代码示例
// controllers/menuItemsController.js
const fs = require('fs');
const path = require('path');
const MenuItem = require('../../models/MenuItem');
const Category = require('../../models/Category');
const Size = require('../../models/Size'); 
const dataPaths = require('../../config/data');
const multer = require('multer');

// 配置Multer存储与编码支持
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'Frontend/img/');
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname);
  }
});

const upload = multer({
  storage: storage,
  limits: {
    fieldNameSize: 255
  }
});

function addItem(req, res) {
    upload.single('image')(req, res, function(err) {
        if (err instanceof multer.MulterError) {
            return res.status(500).json({ message: '上传图片时出错' });
        } else if (err) {
            return res.status(500).json({ message: '内部服务器错误' });
        }
        const { category, name, sizes } = req.body;
        const imageSrc = 'Frontend/img/' + req.file.filename;
        const sizePrice = req.body.sizePrice;
        const sizesWithPrices = [];
        
        // 处理尺寸名称,确保编码正确
        Object.keys(sizePrice).forEach(encodedSizeName => {
            const sizeName = decodeURIComponent(encodedSizeName);
            const price = sizePrice[encodedSizeName];
            if (price !== '') {
                sizesWithPrices.push({
                    name: sizeName,
                    price: parseFloat(price)
                });
            }
        });

        // 执行保存逻辑
        const newItem = new MenuItem(category, name, sizesWithPrices, imageSrc);
        fs.readFile(dataPaths.menuItems, 'utf8', (err, data) => {
            if (err) {
                console.error('读取菜单文件出错:', err);
                return res.status(500).json({ message: '内部服务器错误' });
            }

            const menuItems = JSON.parse(data);
            menuItems.push(newItem);

            fs.writeFile(dataPaths.menuItems, JSON.stringify(menuItems, null, 2), 'utf8', (err) => {
                if (err) {
                    console.error('更新菜单文件出错:', err);
                    return res.status(500).json({ message: '内部服务器错误' });
                }
                res.redirect(`/admincp/menuitems?token=${req.query.token}`);
            });
        });
    });
}

内容的提问来源于stack exchange,提问作者yosf.143

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 10:42:15