這個問題的核心就是解析字串時會有兩次轉義。
---------------------------------------------------
轉義字符(\)對JavaScript中JSON.parse的影響概述
JSON是一個提供了stringify和parse方法的內置對象,前者用於將js對象轉化爲符合json標準的字符串,後者將符合json標準的字符串轉化爲js對象,本文爲大家介紹下轉義字符對JSON.parse方法的影響。
按照ECMA262第五版中的解釋,JSON是一個提供了stringify和parse方法的內置對象,前者用於將js對象轉化爲符合json標準的字符串,後者將符合json標準的字符串轉化爲js對象。json標準參考<a href="http://json.org/" target="_blank">json.org</a>。(其實將符合json標準的字符串轉化爲js對象可以用eval,但是eval性能相對差且存在安全隱患(會執行json字符串中的代碼),本文寫的是轉義字符對JSON.parse方法的影響。
一般來說在JSON.parse的參數包含轉移字符的時候會遇到兩次轉義的問題,其實第一次是字符串本身的轉義,第二次是將真正轉爲js對象的轉義。
舉例如下:
例子一:將字符串'{"a":"b","b":"\\\\"}'傳遞給JSON.parse,首先解析器提取單引號括起來的字符串時認爲第一個\轉義第二個\ 第三個\轉義第四個\,也就是說實際可輸出字符串是{"a":"b","b":"\\"}(可通過console.log('{"a":"b","b":"\\\\"}')驗證),之後正式轉爲js對象的時候還有一次轉義,也就是實際輸出字符轉中的第一個\轉義第二個\(此時只有兩個\)。所以console.log(JSON.parse('{"a":"b","b":"\\\\"}')
);輸出結果爲Object {a: "b", b: "\"},也就是說實際顯示的數據爲一個\(實際可輸出一個\說明在此之前還有一個\)。
例子二:
var obj = {
a : "b",
b : "\\",
c : {
b : "\\",
a : {
b : "\\"
}
}
};
var json_str = JSON.stringify(obj);
console.log( JSON.stringify(obj) );
console.dir(JSON.parse(json_str));
console.dir(JSON.parse('{"a":"b","b":"\\\\","c":{"b":"\\\\","a":{"b":"\\\\"}}}'));輸出結果如下圖
pic
根據轉義規則,實際輸出一個\在這個\之前必定有一個\。所以如上第一行輸出按照書寫來說爲'{"a":"b","b":"\\\\","c":{"b":"\\\\","a":{"b":"\\\\"}}}',可通過第三條輸出來驗證。
總結,如果想在js對象中出現一個\,需要在json字符串中出現四個\ 。
對於其他的其他的特殊字符
1.雙引號("),如果正確出現雙引號應爲\\\"
2.\n,如想想出現正確的換行需要json字符串中是\\n,其實是先對\n中的\轉義,n變成了普通字符,在解析爲js對象的時候n與之前的\(只有一個\了)被解釋爲換行。如下的兩個與此類似。
3.\r,\\r
4.\t,\\t
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在對數據庫取出來的數據(特別是描述信息)裏面含有特殊字符的話,使用JSON.parse將json字符串轉換成json對象的時候會出錯,主要是雙引號,回車換行等影響明顯,左尖括號和右尖括號也會導致顯示問題,所以要在輸出到頁面進行json對象轉換之前將一些特殊符合進行編碼或轉義,下面展示的是C#代碼編碼和轉義幾個常用特殊字符。經過筆者測試,將這些符號編碼和轉義之後,大部分json字符串都可以轉換成json對象了。如果遇到個別問題,應朝着這個方向去查找問題。
- theString = theString.Replace(">", ">");
- theString = theString.Replace("<", "<");
- theString = theString.Replace(" ", " ");
- theString = theString.Replace("\"", """);
- theString = theString.Replace("\'", "'");
- theString = theString.Replace("\\", "\\\\");//對斜線的轉義
- theString = theString.Replace("\n", "\\n"); //注意php中替換的時候只能用雙引號"\n"
- theString = theString.Replace("\r", "\\r");
注意:\r是回到行首,\n是新啓一行,這兩個一般同時出現,應該同時處理。
補充:文字中間的換行,空格在數據庫裏面不以\r\n, ;等形式顯示出來(“本書”與“前80”之間換行,“由”與“曹雪芹”之間空格)
文字:
數據庫:
原文出處:http://blog.csdn.NET/dotNET25/article/details/24475437
-------------------------------------------下面這個和上面文章類似,替換的字符不一樣,那個比較好還不知道。。----------------
Java 中JSON數據特殊字符的處理
JSon 數據中的String 傳遞數據時,需要處理好特殊字符
1 :引號 如果是使用單引號,來括值的話,那String 中 ' 單引號爲特殊字符
2:正斜槓,反斜槓,換行符號等。另外,必須用 (")
而非 (') 表示字符串:
- static StringBuffer string2Json(String s) {
- StringBuffer sb = new StringBuffer ();
- for (int i=0; i<s.length(); i++) {
- char c = s.charAt(i);
- switch (c) {
- case '\"':
- sb.append("\\\"");
- break;
- case '\\':
- sb.append("\\\\");
- break;
- case '/':
- sb.append("\\/");
- break;
- case '\b':
- sb.append("\\b");
- break;
- case '\f':
- sb.append("\\f");
- break;
- case '\n':
- sb.append("\\n");
- break;
- case '\r':
- sb.append("\\r");
- break;
- case '\t':
- sb.append("\\t");
- break;
- default:
- sb.append(c);
- }
- return sb.toString();
- }
文章出處:http://yancc.iteye.com/blog/983918
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Java到JSON特殊字符轉換
由於從服務器後端生成JSON格式的字符串,最後傳遞到客戶端由 eval() 函數動態的生成Javascript,如果JSON字符串格式錯誤,則eval解析會出錯,經常也是最常出錯的是 " ' \r\n 這三個字符,如 {name:'I'am'}解析時會出錯,同樣,由於JavaScript中的字符串可由單引號也可由雙引號引起來,所以雙引號一樣也有這樣問題。另外,字符串是不能跨行寫的,即你不能寫成這樣:{name:"I'
am"}
所以這3個需要轉換,另外換行可能依賴於平臺,所以 \n 也需要轉換,比如我們需要將後臺拋出的異常棧信息以JSON的格式傳回到瀏覽器上顯示時,就需要將回車換行轉換。代碼如下:
- response.setContentType("application/json");
- Writer wr = response.getWriter();
- if(exceptionTrace.indexOf("'")!=-1){
- //將單引號轉義一下,因爲JSON串中的字符串類型可以單引號引起來的
- exceptionTrace = exceptionTrace.replaceAll("'", "\\'");
- }
- if(exceptionTrace.indexOf("\"")!=-1){
- //將雙引號轉義一下,因爲JSON串中的字符串類型可以單引號引起來的
- exceptionTrace = exceptionTrace.replaceAll("\"", "\\\"");
- }
- if(exceptionTrace.indexOf("\r\n")!=-1){
- //將回車換行轉換一下,因爲JSON串中字符串不能出現顯式的回車換行
- exceptionTrace = exceptionTrace.replaceAll("\r\n", "\\u000d\\u000a");
- }
- if(exceptionTrace.indexOf("\n")!=-1){
- //將換行轉換一下,因爲JSON串中字符串不能出現顯式的換行
- exceptionTrace = exceptionTrace.replaceAll("\n", "\\u000a");
- }
- wr.write("{success:false,exception:true,msg:'" +exceptionTrace + "'}");
- wr.flush();
- wr.close();