【问题标题】:Parsing JSON data containing unicode characters解析包含 unicode 字符的 JSON 数据
【发布时间】:2018-06-19 00:29:24
【问题描述】:

我有 UTF8 编码 一个 json 文件,其中包含存储在 AWS S3 存储中的 unicode 字符。为了能够从我的 React 项目下载该文件,我创建了 AWS Gateway API 和 Lambda 函数。在项目中,我使用 Axios 库来下载该文件,并且似乎下载正确(我使用 console.log 检查内容)。但是,当我使用 JSON.parse 解析文件时,出现“字符串文字中的控制字符错误”错误。使用 JSON 验证器检查内容返回肯定结果,并且来自 API Gateway 的 http-response 标头已正确设置为“content-type:application/json”和“charset:utf-8”。 JSON.parse 仅在我从文件中删除所有 UTF8 unicode 字符时才有效。当我删除包含 unicode 字符的部分时,我什至不需要使用 JSON 解析。我可以从我的脚本中将它作为对象访问。这是我的json文件的内容

{
  "en": [
    {
      "Question": "Question 1",
      "Choice": [ "Strongly  Agree", "Agree", "Neither Agree Nor Disagree", "Disagree", "Strongly Disagree" ]
    },
    {
      "Question": "Question 2",
      "Choice": [ "Strongly  Agree", "Agree", "Neither Agree Nor Disagree", "Disagree", "Strongly Disagree" ]
    },
    {
      "Question": "Question 3",
      "Choice": [ "Strongly  Agree", "Agree", "Neither Agree Nor Disagree", "Disagree", "Strongly Disagree" ]
    },
    {
      "Question": "Question 4",
      "Choice": [ "Strongly  Agree", "Agree", "Neither Agree Nor Disagree", "Disagree", "Strongly Disagree" ]
    }
  ],
  "fr": [
    {
      "Question": "Question 1",
      "Choice": [ "Tout À Fait d'Accord", "d'Accord", "Ni En Désaccord Ni d'Accord", "Pas d'Accord", "Pas Du Tout d'Accord"]
    },
    {
      "Question": "Question 2",
      "Choice": [ "Tout À Fait d'Accord", "d'Accord", "Ni En Désaccord Ni d'Accord", "Pas d'Accord", "Pas Du Tout d'Accord"]
    },
    {
      "Question": "Question 3",
      "Choice": [ "Tout À Fait d'Accord", "d'Accord", "Ni En Désaccord Ni d'Accord", "Pas d'Accord", "Pas Du Tout d'Accord"]
    },
    {
      "Question": "Question 4",
      "Choice": [ "Tout À Fait d'Accord", "d'Accord", "Ni En Désaccord Ni d'Accord", "Pas d'Accord", "Pas Du Tout d'Accord"]
    }
  ],
  "pt": [
    {
      "Question": "Questão 1",
      "Choice": [ "Concordo Plenamente", "Aceita", "Não Concordo Nem Discordo", "Discordar", "Discordo Fortemente" ]
    },
    {
      "Question": "Questão 2",
      "Choice": [ "Concordo Plenamente", "Aceita", "Não Concordo Nem Discordo", "Discordar", "Discordo Fortemente" ]
    },
    {
      "Question": "Questão 3",
      "Choice": [ "Concordo Plenamente", "Aceita", "Não Concordo Nem Discordo", "Discordar", "Discordo Fortemente" ]
    },
    {
      "Question": "Questão 4",
      "Choice": [ "Concordo Plenamente", "Aceita", "Não Concordo Nem Discordo", "Discordar", "Discordo Fortemente" ]
    }
  ],
  "my": [
    {
      "Question": "မေးခွန်း ၁",
      "Choice": [ "အပြည့်အ၀ထောက်ခံတယ်", "ထောက်ခံတယ်", "ထောက်ခံတယ်လည်းမဟုတ်ဘူး မထောက်ခံတယ်လည်းမဟုတ်ဘူး", "မထောက်ခံဘူး", "အပြည့်အ၀မထောက်ခံဘူး" ]
    },
    {
      "Question": "မေးခွန်း ၂",
      "Choice": [ "Strongly  Disagree", "Somewhat Disagree", "Agree", "Somewhat Agree", "Strongly Agree" ]
    },
    {
      "Question": "မေးခွန်း ၃",
      "Choice": [ "Strongly  Disagree", "Somewhat Disagree", "Agree", "Somewhat Agree", "Strongly Agree" ]
    },
    {
      "Question": "မေးခွန်း ၄",
      "Choice": [ "Strongly  Disagree", "Somewhat Disagree", "Agree", "Somewhat Agree", "Strongly Agree" ]
    }
  ]
}

编辑 这是负责下载和解析该文件的代码:

    let request = {
        host: process.env.AWS_HOST,
        method: 'GET',
        url: process.env.AWS_URL,
        path: process.env.AWS_PATH
    }

    let signedRequest = aws4.sign(request, {
        secretAccessKey: process.env.AWS_SECRET_KEY,
        accessKeyId: process.env.AWS_ACCESS_KEY
     });


    axios(signedRequest)
        .then(response => {

            console.log(response.data); 

            JSON.parse(response.data); // Error!

        })
        .catch((error) => {
            console.log("error",error);
        });

编辑 我更正了标题以反映我要问的问题。

【问题讨论】:

  • 你用什么编辑器来编辑文件?是否设置为“UTF-8 without BOM”?
  • 我问是因为您说的是“UTF8 字符”。没有 UTF-8 字符。有 Unicode 个字符。 UTF-8 只是将 Unicode 表示为文件中字节的众多方式之一——它是一种编码。并非每个 Unicode 文件都会自动编码为 UTF-8。
  • 你是对的!我将编码与字符集混淆了。感谢您指出了这一点。为了回答您的问题,我使用 Atom 编辑器,它似乎没有 UTF 的“带 BOM”或“不带 BOM”选项
  • 好的,那么你需要展示加载文件的代码。将其缩减为重现错误的最小(如五行)测试程序。此外,从磁盘加载文件作为测试。是否出现同样的错误?
  • 我将代码添加到我的帖子中。我在本地导入了 json 对象,没有任何问题。

标签: json utf-8 axios


【解决方案1】:

我刚刚发现是我的 lambda 函数导致了这个问题。该函数从 s3 存储桶中读取文件并将数据编码为 ascii,然后作为响应返回。将其修复为 utf-8 可解决此问题。感谢@Tomalak 抽出宝贵时间。

const done = (err, res) => callback(null, {
    statusCode: err ? '400' : '200',
    body: err ? err.message :  res.Body.toString('utf-8'), // <<-- this line 
    headers: {
        'Content-Type': 'application/json',
        'Charset': 'utf-8',
        "'Access-Control-Allow-Methods": "GET, POST, OPTIONS"
    },
});

【讨论】:

  • 感谢您发布您的解决方案和解释!
猜你喜欢
  • 2021-12-07
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 2010-12-14
相关资源
最近更新 更多