Come gestisco le newline in JSON?

Ho generato alcuni JSON e sto provando a inserirlo in un object in JavaScript. Continuo a ricevere errori. Ecco cosa ho:

var data = '{"count" : 1, "stack" : "sometext\n\n"}'; var dataObj = eval('('+data+')'); 

Questo mi dà un errore:

 unterminated string literal 

Con JSON.parse(data) , vedo messaggi di errore simili: ” Unexpected token ↵ ” in Chrome e ” unterminated string literal ” in Firefox e IE.

Quando togli il \n dopo il sometext l’errore scompare in entrambi i casi. Non riesco a capire perché \n rende eval e JSON.parse falliscono.

Immagino che questo sia quello che vuoi:

 var data = '{"count" : 1, "stack" : "sometext\\n\\n"}'; 

(È necessario sfuggire alla “\” nella stringa (trasformandola in una doppia “\”), altrimenti diventerà una nuova riga nell’origine JSON, non nei dati JSON.)

Dovrai avere una funzione che sostituisce \n in \\n nel caso in cui i data non siano una stringa letterale.

 function jsonEscape(str) { return str.replace(/\n/g, "\\\\n").replace(/\r/g, "\\\\r").replace(/\t/g, "\\\\t"); } var data = '{"count" : 1, "stack" : "sometext\n\n"}'; var dataObj = JSON.parse(jsonEscape(data)); 

I dataObj risultantiObj saranno

 Object {count: 1, stack: "sometext\n\n"} 

Secondo le specifiche: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf

 A string is a sequence of Unicode code points wrapped with quotation marks (U+0022). All characters may be placed within the quotation marks except for the characters that must be escaped: quotation mark (U+0022), reverse solidus (U+005C), and the control characters U+0000 to U+001F. There are two-character escape sequence representations of some characters. 

Quindi non puoi passare direttamente i codici 0x0A o 0x0C . È vietato! Spec suggerisce di usare sequenze di escape per alcuni codici ben definiti da U+0000 a U+001F :

 \f represents the form feed character (U+000C). \n represents the line feed character (U+000A). 

Dato che la maggior parte dei linguaggi di programmazione usa \ per la citazione, si dovrebbe sfuggire alla syntax di escape (double-escape – una volta per lingua / piattaforma, una volta per Json stesso):

 jsonStr = "{ \"name\": \"Multi\\nline.\" }"; 

Si potrebbe semplicemente sfuggire alla stringa nel server durante la scrittura del valore del campo JSON e non decifrarlo quando si recupera il valore nel browser client, ad esempio.

L’implementazione javascript di tutti i principali browser ha il comando unescape.

Esempio: nel server:

 response.write "{""field1"":""" & escape(RS_Temp("textField")) & """}" 

nel browser:

 document.getElementById("text1").value = unescape(jsonObject.field1) 

Potresti voler esaminare questa funzione in C # per sfuggire alla stringa:

http://www.aspcode.net/C-encode-a-string-for-JSON-JavaScript.aspx

 public static string Enquote(string s) { if (s == null || s.Length == 0) { return "\"\""; } char c; int i; int len = s.Length; StringBuilder sb = new StringBuilder(len + 4); string t; sb.Append('"'); for (i = 0; i < len; i += 1) { c = s[i]; if ((c == '\\') || (c == '"') || (c == '>')) { sb.Append('\\'); sb.Append(c); } else if (c == '\b') sb.Append("\\b"); else if (c == '\t') sb.Append("\\t"); else if (c == '\n') sb.Append("\\n"); else if (c == '\f') sb.Append("\\f"); else if (c == '\r') sb.Append("\\r"); else { if (c < ' ') { //t = "000" + Integer.toHexString(c); string t = new string(c,1); t = "000" + int.Parse(tmp,System.Globalization.NumberStyles.HexNumber); sb.Append("\\u" + t.Substring(t.Length - 4)); } else { sb.Append(c); } } } sb.Append('"'); return sb.ToString(); } 

Salve, ho usato questa funzione per escludere newline o altri caratteri nei dati per analizzare i dati JSON:

 function normalize_str($str) { $invalid = array('Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', "`" => "'", "´" => "'", '"' => ',', '`' => "'", '´' => "'", '"' => '\"', '"' => "\"", '´' => "'", "’" => "'", "{" => "", "~" => "", "–" => "-", "'" => "'"," " => " "); $str = str_replace(array_keys($invalid), array_values($invalid), $str); $remove = array("\n", "\r\n", "\r"); $str = str_replace($remove, "\\n", trim($str)); //$str = htmlentities($str,ENT_QUOTES); return htmlspecialchars($str); } echo normalize_str($lst['address']); 

Ho riscontrato questo problema mentre facevo una class in PHP4 per emulare json_encode (disponibile in PHP5). Ecco cosa mi è venuto in mente:

 class jsonResponse { var $response; function jsonResponse() { $this->response = array('isOK'=>'KO','msg'=>'Undefined'); } function set($isOK, $msg) { $this->response['isOK'] = ($isOK) ? 'OK' : 'KO'; $this->response['msg'] = htmlentities($msg); } function setData($data=null) { if(!is_null($data)) $this->response['data'] = $data; elseif(isset($this->response['data'])) unset($this->response['data']); } function send() { header('Content-type: application/json'); echo '{"isOK":"'.$this->response['isOK'].'","msg":'.$this->parseString($this->response['msg']); if(isset($this->response['data'])) echo ',"data":'.$this->parseData($this->response['data']); echo '}'; } function parseData($data) { if(is_array($data)) { $parsed = array(); foreach ($data as $key=>$value) array_push($parsed, $this->parseString($key).':'.$this->parseData($value)); return '{'.implode(',', $parsed).'}'; } else return $this->parseString($data); } function parseString($string) { $string = str_replace("\\", "\\\\", $string); $string = str_replace('/', "\\/", $string); $string = str_replace('"', "\\".'"', $string); $string = str_replace("\b", "\\b", $string); $string = str_replace("\t", "\\t", $string); $string = str_replace("\n", "\\n", $string); $string = str_replace("\f", "\\f", $string); $string = str_replace("\r", "\\r", $string); $string = str_replace("\u", "\\u", $string); return '"'.$string.'"'; } } 

Ho seguito le regole menzionate qui . Ho usato solo ciò di cui avevo bisogno ma immagino che tu possa adattarlo alle tue esigenze nella lingua che stai usando. Il problema nel mio caso non riguardava le newline come inizialmente pensavo, ma il / non essere scappato. Spero che questo impedisca a qualcun altro dal piccolo mal di testa di aver capito cosa ho fatto di sbagliato.