如果只存在一个非法字符,使用 utf-8 的字符编码会破坏所有数据
Character encoding with utf-8 breaks all data if just one illegal character is present
在我的应用程序中通过 REST 服务读取数据时,我有一个奇怪的行为。
我总是用 utf-8
编码我的 REST 服务。这已被证明是一个 安全的选择 - 直到现在。我来自丹麦,我们有一些特殊字符,例如:æøå。
所以对于这组特定的数据,用户在应用程序中输入了一个笑脸 - 并且数据已同步到服务器。当数据随后被发送回phone ALL时,请求中的数据得到"scrambled"。如果我在任何其他工具(如各种浏览器,例如 PostMan)中尝试相同的请求,那么一切看起来都正常(字符集是 utf-8
,只有笑脸无法显示)。但是,在我的应用程序中,所有非英语字符都被打乱了。
单击 here to see the url with the smiley - and here 以查看没有笑脸的 url(只是不同的截止时间)。 编辑:链接不再有效....
我创建了一个小的测试应用程序来从 Appcelerator 内部显示问题:
查看:
<Alloy>
<Window class="container">
<View>
<Button id="label1" class="heading" onClick="reload1">Load with smiley</Button>
<Button id="label2" class="heading" onClick="reload2">Load without smiley</Button>
<ListView id="nameList" defaultItemTemplate="templateName">
<Templates>
<ItemTemplate name="templateName">
<Label bindId="name"/>
</ItemTemplate>
</Templates>
<ListSection>
<ListItem/>
</ListSection>
</ListView>
</View>
</Window>
</Alloy>
风格:
".container": {
top: 20,
backgroundColor:"white",
orientationModes: [Ti.UI.PORTRAIT]
}
"Label": {
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
backgroundColor: 'transparent',
left:10,
color: "#000"
}
".heading": { top:15,
font: {
fontSize: '18dp',
fontStyle: 'bold'
}
}
"#label1":{left: 10}
"#label2":{right: 10}
"#nameList":{
top:'50dp'
}
控制器:
function reload1(){
reload('http://url1');
}
function reload2(){
reload('http://url2');
}
function reload(url){
var list = [];
$.nameList.sections[0].items = [];
var xhr = Ti.Network.createHTTPClient({
timeout : 20000
});
var name = 'speciesName';
xhr.open('GET', url);
xhr.onload = function(e) {
var responseJSON = {};
Ti.API.info("Response headers: " + this.getAllResponseHeaders());
try {
responseJSON = JSON.parse(this.responseText);
if(responseJSON.data){
_.each(responseJSON.data,function(rec){
if(rec[name] && rec[name] != ''){
var item = {template: "templateName",name : { text: rec[name] }};
list.push(item);
}
});
$.nameList.sections[0].items = list;
}
} catch (e) {
Ti.API.error('[REST API] apiCall PARSE ERROR: ' + e.message);
Ti.API.error('[REST API] apiCall PARSE ERROR: ' + this.responseText);
status = false;
error = e.message;
}
};
// function called when an error occurs, including a timeout
xhr.onerror = function(e) {
Ti.API.debug(e.error);
alert('error');
};
xhr.send();
}
$.index.open();
reload1();
当您启动应用程序时,它会显示 "scrambled" 个字符的数据。然后,您可以使用顶部的按钮在数据集 with/without 和笑脸之间切换。
问题在 iOS 和 Android 上是一致的。我是 运行 Ti SDK 5.1.2
- 在提交 "real" 应用程序更新之前我不敢升级 :-)
理想情况下,我还希望能够在移动设备上显示笑脸。但是,我可以忍受它没有正确显示 - 只要它不会破坏整个数据集。
非常感谢 thoughts/ideas/insight:-)
/约翰
所以字符串从服务器返回为:
"comments":"Huggede under træet og gav en helt fantastisk fight.\nMin stang knækkede og jeg dumpede i åen??????"
笑脸表情符号已作为 UTF-8 代码单元发送:ed a0 bd ed b8 80
它们应该 JSON/JS 转义为 \uD83D\uDE00
=
这是查看编码问题的好资源https://r12a.github.io/apps/conversion/
好的。结果证明这是一个与 Titanium/Appcelerator 无关的问题 - 除了如果只有一个字符不适合字符集,整个请求就会被破坏。
后端服务器是 IBM XWork 服务器,结果发现 REST 服务使用了发送字符的 ResponseWriter (Java)。在发送字节流的 DataOutputStream (Java) 将其更改为 return 解决了问题。
如果其他人 运行 遇到类似的问题,那么我已经写了一篇 blog article about this,您可以在其中了解更多信息。该解决方案并非特定于 IBM XWork - 但适用于使用 Java :-)
的任何后端
/约翰
在我的应用程序中通过 REST 服务读取数据时,我有一个奇怪的行为。
我总是用 utf-8
编码我的 REST 服务。这已被证明是一个 安全的选择 - 直到现在。我来自丹麦,我们有一些特殊字符,例如:æøå。
所以对于这组特定的数据,用户在应用程序中输入了一个笑脸 - 并且数据已同步到服务器。当数据随后被发送回phone ALL时,请求中的数据得到"scrambled"。如果我在任何其他工具(如各种浏览器,例如 PostMan)中尝试相同的请求,那么一切看起来都正常(字符集是 utf-8
,只有笑脸无法显示)。但是,在我的应用程序中,所有非英语字符都被打乱了。
单击 here to see the url with the smiley - and here 以查看没有笑脸的 url(只是不同的截止时间)。 编辑:链接不再有效....
我创建了一个小的测试应用程序来从 Appcelerator 内部显示问题:
查看:
<Alloy>
<Window class="container">
<View>
<Button id="label1" class="heading" onClick="reload1">Load with smiley</Button>
<Button id="label2" class="heading" onClick="reload2">Load without smiley</Button>
<ListView id="nameList" defaultItemTemplate="templateName">
<Templates>
<ItemTemplate name="templateName">
<Label bindId="name"/>
</ItemTemplate>
</Templates>
<ListSection>
<ListItem/>
</ListSection>
</ListView>
</View>
</Window>
</Alloy>
风格:
".container": {
top: 20,
backgroundColor:"white",
orientationModes: [Ti.UI.PORTRAIT]
}
"Label": {
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
backgroundColor: 'transparent',
left:10,
color: "#000"
}
".heading": { top:15,
font: {
fontSize: '18dp',
fontStyle: 'bold'
}
}
"#label1":{left: 10}
"#label2":{right: 10}
"#nameList":{
top:'50dp'
}
控制器:
function reload1(){
reload('http://url1');
}
function reload2(){
reload('http://url2');
}
function reload(url){
var list = [];
$.nameList.sections[0].items = [];
var xhr = Ti.Network.createHTTPClient({
timeout : 20000
});
var name = 'speciesName';
xhr.open('GET', url);
xhr.onload = function(e) {
var responseJSON = {};
Ti.API.info("Response headers: " + this.getAllResponseHeaders());
try {
responseJSON = JSON.parse(this.responseText);
if(responseJSON.data){
_.each(responseJSON.data,function(rec){
if(rec[name] && rec[name] != ''){
var item = {template: "templateName",name : { text: rec[name] }};
list.push(item);
}
});
$.nameList.sections[0].items = list;
}
} catch (e) {
Ti.API.error('[REST API] apiCall PARSE ERROR: ' + e.message);
Ti.API.error('[REST API] apiCall PARSE ERROR: ' + this.responseText);
status = false;
error = e.message;
}
};
// function called when an error occurs, including a timeout
xhr.onerror = function(e) {
Ti.API.debug(e.error);
alert('error');
};
xhr.send();
}
$.index.open();
reload1();
当您启动应用程序时,它会显示 "scrambled" 个字符的数据。然后,您可以使用顶部的按钮在数据集 with/without 和笑脸之间切换。
问题在 iOS 和 Android 上是一致的。我是 运行 Ti SDK 5.1.2
- 在提交 "real" 应用程序更新之前我不敢升级 :-)
理想情况下,我还希望能够在移动设备上显示笑脸。但是,我可以忍受它没有正确显示 - 只要它不会破坏整个数据集。
非常感谢 thoughts/ideas/insight:-)
/约翰
所以字符串从服务器返回为:
"comments":"Huggede under træet og gav en helt fantastisk fight.\nMin stang knækkede og jeg dumpede i åen??????"
笑脸表情符号已作为 UTF-8 代码单元发送:ed a0 bd ed b8 80
它们应该 JSON/JS 转义为 \uD83D\uDE00
=
这是查看编码问题的好资源https://r12a.github.io/apps/conversion/
好的。结果证明这是一个与 Titanium/Appcelerator 无关的问题 - 除了如果只有一个字符不适合字符集,整个请求就会被破坏。
后端服务器是 IBM XWork 服务器,结果发现 REST 服务使用了发送字符的 ResponseWriter (Java)。在发送字节流的 DataOutputStream (Java) 将其更改为 return 解决了问题。
如果其他人 运行 遇到类似的问题,那么我已经写了一篇 blog article about this,您可以在其中了解更多信息。该解决方案并非特定于 IBM XWork - 但适用于使用 Java :-)
的任何后端/约翰