【问题标题】:UTF-8 string not decoded correctly in AngularJSUTF-8 字符串在 AngularJS 中未正确解码
【发布时间】:2017-06-02 18:27:44
【问题描述】:

我有一个文本输入框,在基于 AngularJS 的 SPA 中,供用户为打印输出添加标题。输入框声明如下:

<input class="chart-title" type="text" ng-model="chartTitle" ng-change="titleChanged()"/>

文本框由服务器提供的默认标题填充。用户可以将标题更改为适合他们的任何内容。当标题更改时,服务器会更新并在响应的标题中发回一个新标题,然后替换框中的标题。这对标准 ASCII 类型字符非常有效。

但是,对于 unicode 字符(例如 àßéçøö),它不起作用。文本正确发送,在服务器上正确更新,并正确返回到 SPA。请求/响应的标头在这里:

Request URL:http://blahblahblah/api/.....&chartTitle=Instrument:%20%C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6

响应标头:

chartTitle: Instrument: %C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6

请求是使用 AngularJS $http() 发出的。如您所见,值匹配(出于显而易见的原因,请求代码中的空格为%20)。但是,当我使用headers("charttitle") 检索标头时,我收到的值是Instrument: àÃéçøö

javascript 包在索引中用 charset utf-8 声明:

<script src="/js/bundle.js" type="text/javascript" charset="UTF-8"></script>

此外,html 是用正确的字符集声明的,在我看来,在 head 声明中的两个地方:

<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
<meta charset="utf-8" />

根据本网站 (http://www.i18nqa.com/debug/utf8-debug.html) 看来,我正在获取 Windows1252 字符编码。这没有任何意义。如果绝对有必要,我可以编写一个可怕的 hack,将 utf-8 字符串转换为 Windows1252 字符,但这似乎有点极端,而且对我来说很容易出错。

无论是在 Chrome、Firefox 还是 IE11 上,效果都是一样的。完整的请求标头在这里:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Host:blahblahblah
Origin:http://blahblahblah
Referer:http://blahblahblah/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

有什么我遗漏的吗?有什么忘记了吗?

编辑

根据要求提供完整的响应标头。

Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:chartTitle
Cache-Control:private
chartTitle:Instrument: %C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6
Content-Disposition:attachment; filename=PrintData.pdf
Content-Length:1391643
Content-Type:application/octet-stream
Date:Fri, 20 Jan 2017 11:19:07 GMT
Server:Microsoft-IIS/10.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcR2l0XEVPU1xSZXZpZXdlci5XZWJcYXBpXFByaW50XGQyOTNkNjA4NWVlYzlhNTEwYjQ5YThmZGQxNjNhMjAwMWZhYTFjMGY5YzhiMzUxYzE5ZjYxYWMwYTY1OWVhMDM=?=

headers周围的代码

$http({
    method: 'GET',
    url: filePath,
    params: {
        fileName: fileName
    },
    responseType: 'arraybuffer',
    headers: {'Content-Type' : 'application/json; charset=UTF-8'}
}).success(function (data, status, headers) {
    ready();
    if (status == 200) {
        var chartTitle = headers("charttitle");
        var printoutInformation = {'chartTitle' : chartTitle, 'pdfData' : data};
        deferred.resolve(printoutInformation);
    }
    else {
        deferred.resolve(null);
    }
    }).error(function (data) {
        ready();
        console.log(data);
    });
    return deferred.promise;

编辑

api 的web.config 也指定了utf-8:

    <globalization requestEncoding="utf-8" responseEncoding="utf-8"/>

TL;DR

在文本框中,我想显示“Instrument àßéçøö”,而我看到的是“Instrument: à éçøö”

【问题讨论】:

  • 什么是完整的 response 标头?围绕headers('charttitle') 的简短但完整的代码示例也会有所帮助。
  • @deceze - 我已经编辑了问题以添加代码示例和完整的响应标头。
  • responseType: 'arraybuffer' 是必要的吗?
  • @Sravan - 是的,因为响应是作为字节数组的 pdf
  • @deceze - 如果有帮助,添加 web.config 信息

标签: javascript angularjs string utf-8 character-encoding


【解决方案1】:

你的问题解决了。

基于此来源,

UTF-8 character debugging and its encoding and decoding

您得到的响应是编码的 utf-8 字符串的实际字符

因此,您需要对其进行解码才能获得结果。

这是执行此操作的代码。

    decoded =  decodeURIComponent('%C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6')

    console.log(decoded);

   The result is => "àßéçøö"

我们必须这样做才能得到实际的字符串而不是 UTF-8

所以,从你得到的回复中,à Ãéçøö

decodeURIComponent(escape("à Ãéçøö")) =&gt; "àßéçøö"

定义:

decodeURIComponent():

  • 表示给定编码统一资源标识符 (URI) 组件的解码版本的新字符串。

所以,这是你的方法。

if (status == 200) {
    var original = headers("charttitle");
    var chartTitle = decodeURIComponent(escape(original));
    console.log(chartTitle);
    var printoutInformation = {'chartTitle' : chartTitle, 'pdfData' : data};
    deferred.resolve(printoutInformation);
}

现在,您将获得与发送相同的标题。

【讨论】:

  • 感谢斯拉万的回答。但是,我不想要“%C3%83%20%C3%83%C3%83%C2%A9%C3%83%C2%A7%C3%83%C2%B8%C3%83%C2%B6” .我想要的是原始字符:“仪器:àßéçøö”。有没有办法从一个到另一个?
  • 你需要什么结果?
  • 我需要“仪器:àßéçøö”。我得到“仪器:ÃÃéçøö”
  • @Sravan- 我添加了有关 web api web.config 文件的信息,如果有帮助?
  • 是的。它没有回答我的问题。
【解决方案2】:

试试下面的编码

myAngApp1=document.getElementById("ItemSearch"); var uri = myAngApp1.value; var place = encodeURIComponent(uri)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 2015-05-09
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多