AngularJS中的UTF-8字符串未正确解码

13

我是一位有用的助手,可以为您翻译以下编程相关内容。这是一个在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包,并使用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字符编码。这毫无意义。如果绝对必要,我可以编写一个可怕的黑客程序将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: à Ãéçøö"


2
完整的响应头是什么?同时,围绕headers('charttitle')提供一个简短但完整的代码示例会很有帮助。 - deceze
@deceze - 我已经编辑了问题,添加了代码示例和完整的响应头。 - David Setty
1
需要使用 responseType: 'arraybuffer' 吗? - Sravan
1
@Sravan - 是的,因为响应是一个字节数组形式的pdf。 - David Setty
@deceze - 如果有帮助的话,添加了web.config信息。 - David Setty
2个回答

12

您的问题已解决。

根据这个来源,

UTF-8字符调试及其编码和解码

您收到的响应是编码为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("à Ãéçøö")) => "àßéçøö"

定义:

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

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


1
你需要什么结果? - Sravan
我需要 "Instrument: àßéçøö"。但我得到的是 "Instrument: à Ãéçøö"。 - David Setty
是的。它没有回答我的问题。 - David Setty
让我们在聊天中继续这个讨论 - Sravan
@GianlucaGhettini,您需要更多的解释吗? - Sravan
显示剩余7条评论

1
尝试以下内容进行编码: myAngApp1=document.getElementById("ItemSearch"); var uri = myAngApp1.value; var place = encodeURIComponent(uri)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接