2008-09-03 41 views
193

Tôi đã tạo một số JSON và tôi đang cố gắng đưa nó vào một đối tượng trong JavaScript. Tôi tiếp tục gặp lỗi. Dưới đây là những gì tôi có:Làm cách nào để xử lý dòng mới trong JSON?

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

này mang lại cho tôi một lỗi:

unterminated string literal 

Với JSON.parse(data), tôi thấy thông báo lỗi tương tự: "Unexpected token ↵" trong Chrome, và "unterminated string literal" trong Firefox và IE.

Khi tôi lấy ra \n sau sometext lỗi sẽ biến mất trong cả hai trường hợp. Tôi không thể tìm ra lý do tại sao các \n làm cho evalJSON.parse không thành công.

+7

Hãy thử sử dụng trình phân tích cú pháp json thực thay vì eval. – Eric

Trả lời

257

Tôi đoán đây là những gì bạn muốn:

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

(Bạn cần phải thoát khỏi "\" trong chuỗi của bạn (biến nó thành một đôi - "\"), nếu không nó sẽ trở thành một dòng mới trong . nguồn JSON, không phải là dữ liệu JSON)

+63

Điều này tất nhiên là đúng, nhưng tôi muốn thêm lý do cho việc phải làm điều này: thông số kỹ thuật JSON tại http://www.ietf.org/rfc/rfc4627.txt chứa câu này trong phần 2.5: "Tất cả Ký tự Unicode có thể được đặt trong dấu ngoặc kép ngoại trừ các ký tự phải được thoát: dấu ngoặc kép, dấu gạch chéo ngược và các ký tự điều khiển (U + 0000 đến U + 001F). " Vì một dòng mới là một ký tự điều khiển, nó phải được thoát. –

+0

Theo www.json.org JSON chấp nhận chuỗi điều khiển "\ n" trong chuỗi - và nếu bạn thử JSON.parse (['"a \\ na"']) [1] .charCodeAt(); sẽ hiển thị 10 - đó là "Linefeed" lần cuối tôi kiểm tra. --- BTW: Đừng hét nữa! – BlaM

2

Bạn có thể muốn nhìn vào C# chức năng này để thoát khỏi chuỗi:

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(); 
} 
+1

Bạn nên làm sạch mã đó lên một chút ... (Không biên dịch.) –

+2

Tại sao điều này thoát '>'? – nothingisnecessary

19

Bạn sẽ cần có chức năng thay thế \n thành \\n trong trường hợp data không phải là một chuỗi chữ.

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)); 

Kết quả dataObj sẽ

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

bạn cần phải thoát khỏi các ký tự thoát của bạn (ví dụ '.replace (" \\ n "," \\\\\\ ")') và tôi cũng khuyên bạn nên sử dụng regex để cho phép thay thế nhiều trường hợp (tức là '.replace (/ \ n/g, "\\\\\") ') – musefan

+2

tại sao bạn cần thoát khỏi các ký tự thoát? Tôi có nghĩa là một cái gì đó như '.replace (" \ n "," \\ n ")' nên làm công việc tốt !! Ví dụ: 'var test = [{" description ":" Một số mô tả về sản phẩm. Đây có thể là văn bản nhiều dòng. "}]; console.log (JSON.parse (test.replace (/ \ n/g, "\\ n"))); 'sẽ xuất ra đối tượng hoàn toàn tốt với giao diện điều khiển trình duyệt dưới dạng' [{"description": "Một số mô tả về sản phẩm. \ nĐây có thể là văn bản nhiều dòng. "}]' – Fr0zenFyr

+0

BTW, trong nhận xét ở trên, chuỗi JSON gốc có một dòng mới, được xóa bởi trình định dạng nhận xét của stackoverflow .. Bạn có thể thấy rằng kết quả cuối cùng sau khi thay thế sẽ chèn một dòng mới '' n' trong giá trị. – Fr0zenFyr

0

tôi gặp phải vấn đề mà trong khi làm cho một lớp trong PHP4 để thi đua json_encode (có sẵn trong PHP5). Dưới đây là những gì tôi đã đưa ra:

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.'"'; 
    } 
} 

Tôi tuân thủ các quy tắc được đề cập here. Tôi chỉ sử dụng những gì tôi cần nhưng tôi hình rằng bạn có thể thích nghi nó với nhu cầu của bạn bằng ngôn ngữ bạn đang sử dụng. Vấn đề trong trường hợp của tôi không phải là về dòng mới như tôi nghĩ ban đầu nhưng về/không bị trốn thoát. Tôi hy vọng điều này ngăn chặn người khác khỏi nhức đầu nhỏ tôi đã tìm ra những gì tôi đã làm sai.

+0

6 ký tự viết tắt của các ký tự điều khiển được chỉ định trên json.org không phải là danh sách đầy đủ của tất cả các ký tự điều khiển. Kết quả là, hàm này có thể tạo JSON không hợp lệ. – Phil

2

Hi i sử dụng chức năng này để dải xuống dòng hoặc ký tự khác trong dữ liệu để phân tích dữ liệu 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', "`" => "'", "´" => "'", '"' => ',', '`' => "'", 
    '´' => "'", '"' => '\"', '"' => "\"", '´' => "'", "&acirc;€™" => "'", "{" => "", 
    "~" => "", "–" => "-", "'" => "'","  " => " "); 

    $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']); 
+6

Trong hầu hết các ngôn ngữ, bạn có cách tốt hơn để tách dấu trọng âm khỏi chuỗi unicode hơn là viết ra chức năng ánh xạ của riêng bạn. Xem câu hỏi này cho một ví dụ trong python: http: // stackoverflow.com/questions/517923/what-is-the-best-way-to-remove-dấu-in-a-python-unicode-string – MiniQuark

+0

ya chúng tôi có nhiều cách để kiểm soát các ký tự đặc biệt trong các ngôn ngữ khác nhau. – ShivarajRH

+1

Đó là tất cả các loại xấu để tước chúng nói chung. Mã hoá tốt hơn chúng dưới dạng tham chiếu ký tự số XML và sau đó giải mã khi nhận kết thúc. – Annarfych

2

Bạn chỉ có thể thoát khỏi chuỗi của bạn trong máy chủ khi viết giá trị của lĩnh vực json và unescape nó khi lấy giá trị trong trình duyệt máy khách, ví dụ.

Việc triển khai javascript của tất cả trình duyệt chính có lệnh unescape.

Ví dụ: trong máy chủ:

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

trong trình duyệt:

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

Theo spec: 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. 

Vì vậy, bạn không thể vượt qua 0x0A hoặc 0x0C mã trực tiếp. Nó bị cấm! Spec gợi ý để sử dụng chuỗi thoát cho một số mã được xác định rõ U+0000-U+001F:

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

Vì hầu hết các ngôn ngữ lập trình sử dụng \ cho trích dẫn bạn nên thoát khỏi cú pháp thoát (double-escape - một lần cho ngôn ngữ/nền tảng, một lần cho Bản thân Json):

jsonStr = "{ \"name\": \"Multi\\nline.\" }"; 
Các vấn đề liên quan