2016-04-22 50 views
1

從我的應用程序中通過REST服務讀取數據時,我有一種奇怪的行爲。如果只有一個非法字符,使用utf-8編碼的字符編碼會中斷所有數據

我總是用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 - 我不敢升級,直到我很快提交了更新到我的「真實」應用程序:-)

理想情況下,我也希望能夠在移動設備上顯示笑臉。但是,我可以忍受它不能正確顯示 - 只要它不損壞整個數據集。

任何想法/創意/洞察力非常感謝:-)

/約翰

回答

0

好吧,原來這是一個與Titanium/Appcelerator無關的問題 - 除了只有一個字符不適合字符集的情況下,整個請求被破壞的情況除外

後端服務器是IBM XWork服務器,事實證明REST服務使用了發送字符的ResponseWriter(Java)。改變這個以返回發送字節流的DataOutputStream(Java)來解決問題。

如果有其他人遇到類似的問題,我寫了一個blog article about this在哪裏你可以瞭解更多。該解決方案是不特定的IBM XWork的 - 而是適用於使用Java任何後端:-)

/約翰

1

因此字符串從服務器回來爲:下træetOG「Huggede:

」意見「 gav en helt fantastisk fight。\ nMin stangknækkedeog jeg dumpede iåen??????「

笑臉的表情符號已發送爲UTF-8編碼單元:ed a0 bd ed b8 80

他們應該被JSON/JS轉義爲\uD83D\uDE00 =

這是在看編碼問題的一個很好的資源https://r12a.github.io/apps/conversion/

+0

感謝您的TiSlack的評論和討論。事實證明,這是一個更長的解決方案之旅 - 正如我已經寫了一個答案:-) –