2010-07-13 25 views
5

tôi nhận thấy rằng jQuery parseJSON cơ bản nào một regex đơn giản "kiểm tra":Có nên sử dụng các phương thức parseJSON/getJSON của jQuery không?

parseJSON: function(data) { 
    if (typeof data !== "string" || !data) { 
     return null; 
    } 

    // Make sure leading/trailing whitespace is removed (IE can't handle it) 
    data = jQuery.trim(data); 

    // Make sure the incoming data is actual JSON 
    // Logic borrowed from http://json.org/json2.js 
    if (/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") 
     .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") 
     .replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) { 

     // Try to use the native JSON parser first 
     return window.JSON && window.JSON.parse ? 
      window.JSON.parse(data) : 
      (new Function("return " + data))(); 

    } else { 
     jQuery.error("Invalid JSON: " + data); 
    } 
}, 

Nếu nó đi mà "kiểm tra" và nếu đó là một trình duyệt hiện đại một phân tích cú pháp JSON có nguồn gốc được sử dụng. Nếu không, tôi giả định cho một trình duyệt như IE6 một chức năng mới được tự động gọi và trả về đối tượng.

Câu hỏi # 1: Vì đây chỉ là một thử nghiệm regex đơn giản, điều này có dễ bị khai thác cạnh tối nghĩa không? Có nên chúng ta thực sự không sử dụng trình phân tích cú pháp đầy đủ, đối với các trình duyệt không hỗ trợ phân tích cú pháp JSON gốc ít nhất?

Câu hỏi # 2: Bao nhiêu "an toàn hơn" là (new Function(" return " + data))() thay vì eval("(" + text + ")")?

Trả lời

3

Như đã đề cập trong các ý kiến ​​có trình phân tích cú pháp JSON của jQuery "mượn" logic để kiểm tra xem chuỗi JSON có hợp lệ không, ngay từ json2.js. Điều này làm cho nó "an toàn" như việc thực hiện phi bản địa phổ biến nhất, đó là khá nghiêm ngặt anyway:

// In the second stage, we run the text against regular expressions that look 
// for non-JSON patterns. We are especially concerned with '()' and 'new' 
// because they can cause invocation, and '=' because it can cause mutation. 
// But just to be safe, we want to reject all unexpected forms. 

// We split the second stage into 4 regexp operations in order to work around 
// crippling inefficiencies in IE's and Safari's regexp engines. First we 
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 
// replace all simple value tokens with ']' characters. Third, we delete all 
// open brackets that follow a colon or comma or that begin the text. Finally, 
// we look to see that the remaining characters are only whitespace or ']' or 
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 

      if (/^[\],:{}\s]*$/. 
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). 
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). 
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

Những gì tôi không hiểu là tại sao jQuery chạy biểu thức chính quy/thay thế trước khi kiểm tra cho một việc thực hiện nguồn gốc sẽ kiểm tra ngữ pháp JSON chính xác. Có vẻ như nó sẽ tăng tốc mọi thứ để chỉ thực hiện việc này nếu việc triển khai bản địa không khả dụng.

Câu hỏi 2 là answered very well by bobince trong một câu hỏi khác:

Nó không thực sự là một sự khác biệt lớn, nhưng cảm giác là eval là ‘xấu’ hơn Chức năng mới. Không phải về an ninh - chúng đều vô dụng khi đối mặt với đầu vào không đáng tin cậy, nhưng hy vọng webapp của bạn không trả về các chuỗi JSON không đáng tin cậy - nhưng xét về độ lạ cấp độ ngôn ngữ, và do đó khả năng chống tối ưu hóa.

Kiểm tra Nick Craver's answer cũng có trích dẫn trực tiếp từ John Resig.

0

Phương thức JSON.parse là an toàn nhất. Điều này được xác định khi bạn bao gồm json2.js từ http://www.json.org/js.html và được sử dụng tự động bởi parseJSON/getJSON. Nó phân tích cú pháp thay vì thực thi đánh dấu JSON.

+3

json2.js sẽ sử dụng cùng một regex, và sau đó là 'eval', nếu không có sẵn JSON gốc. –

+0

Lưu ý. Cảm ơn bạn đã làm rõ. – spoulson

Các vấn đề liên quan