如果只存在一个非法字符,使用utf-8进行字符编码会中断所有数据

时间:2016-04-22 10:25:15

标签: character-encoding appcelerator appcelerator-titanium

从我的应用程序中通过REST服务读取数据时,我有一种奇怪的行为。

我总是使用utf-8对我的REST服务进行编码。事实证明,这是 安全 的选择 - 直到现在。我来自丹麦,我们有一些特殊角色,如:æøå。

因此,使用此特定数据集,用户在应用程序中输入了笑脸 - 并且数据已同步到服务器。当数据随后被发送回手机 所有 时,请求中的数据会被“加扰”。如果我在任何其他工具(例如各种浏览器和PostMan)中尝试相同的请求,那么一切看起来都很好(字符集为utf-8且只有笑脸无法显示)。但是,在我的应用程序中,所有非英语字符都会被扰乱。

点击here查看带笑脸的网址 - 和here查看没有笑脸的网址(只是截止时间不同)。 编辑:链接不再有效....

我创建了一个小型测试应用程序来显示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();

启动应用程序时,它会显示带有“乱码”字符的数据。然后,您可以使用顶部的按钮在带/不带笑脸的数据集之间切换。

问题在iOS和Android上是一致的。我正在运行Ti SDK 5.1.2 - 我不敢升级,直到我很快向我的“真实”应用程序提交更新: - )

理想情况下,我还希望能够在移动设备上显示笑脸。但是,我可以忍受它没有正确显示 - 只要它不会破坏整个数据集。

非常感谢任何想法/想法/见解: - )

/约翰

2 个答案:

答案 0 :(得分:1)

因此字符串将从服务器返回:

“评论”:“Huggede在træetoggav en helt fantastisk的战斗。\ nMinstangknækkedeogjeg dumpedeiåen??????”

笑脸表情符号已作为UTF-8代码单位发送:ed a0 bd ed b8 80

它们应该是JSON / JS转义为\uD83D\uDE00 =

这是查看编码问题的好资源https://r12a.github.io/apps/conversion/

答案 1 :(得分:0)

确定。事实证明这是一个与Titanium / Appcelerator无关的问题 - 除了整个请求被破坏,如果只有一个字符不适合字符集。

后端服务器是IBM XWork服务器,结果发现REST服务使用了发送字符的ResponseWriter(Java)。将此更改为在发送字节流的DataOutputStream(Java)处返回,这样就解决了问题。

如果其他人遇到类似的问题,那么我写了blog article about this,你可以在那里了解更多。该解决方案并非特定于IBM XWork - 但适用于使用Java的任何后端: - )

/约翰