Chuỗi thoát trong ngữ cảnh eval với JSON.stringify
Trước hết: Tôi biết rằng có rất nhiều câu hỏi liên quan đến việc trốn thoát, nhưng tôi không tìm thấy câu trả lời chung cho đến nay. Giả sử tôi có chức năng đồ chơi đơn giản này để trình diễn:
function f(somePOJO) {
var s = eval("'" + JSON.stringify(somePOJO) + "';"); // for demonstration only
return JSON.parse(s);
}
const clone = f({a: 1, b: "c"});
Với một đối tượng theo nghĩa đen như {a: 1, b: "c"}(một POJO), fsẽ trả về một "bản sao" của nó. (Lưu ý rằng tôi không thực sự sử dụng cách tiếp cận này để nhân bản hoặc tương tự, và tôi biết rằng đó evallà điều xấu và thậm chí nó không cần thiết ở đây, nó chỉ để chứng minh vấn đề thoát!)
Điều này hoạt động tốt, nhưng chỉ miễn là các giá trị POJO không chứa a '. Tất nhiên bây giờ tôi có thể thoát khỏi JSON bằng cách sử dụng một cái gì đó như JSON.stringify(somePOJO).replace(/'/g, "\\'"). Điều này hoạt động nếu các giá trị POJO chứa ', nhưng không hoạt động nếu chúng chứa \\'. Và điều này tạo ra một vòng xoáy thoát ...
Có một giải pháp cho điều này ở tất cả?
Trả lời
Hàm thoát để bảo toàn chuỗi JSON thông qua việc được đánh giá bởi evalhàm, trình biên dịch JavaScript trong một số trường hợp hoặc bởi JSON.parsehàm thực sự là như vậy JSON.stringify. Đây JSONphương pháp sẽ giá trị chuỗi hạnh phúc stringify, không chỉ là đối tượng kiểu dữ liệu.
function f(somePOJO) {
var s = eval( JSON.stringify(JSON.stringify(somePOJO)) );
return JSON.parse(s);
}
const obj = {a: 1, b: "c", d: "back\\, forward/"}
const clone = f(obj);
console.log(obj);
console.log(clone);
Lý do nó không phải là một trong các escape/encodeURI/encodeURIComponenthọ hàm là vì chúng dùng để thoát các ký tự để đưa vào URL trong khi trường hợp này là về việc thoát các ký tự để được phân tích cú pháp bởi trình phân tích cú pháp JavaScipt.
Trong hầu hết các trường hợp, đặc biệt là để phân tích cú pháp văn bản JSON bằng cách sử dụng JSON.parse, việc xâu chuỗi văn bản JSON lần thứ hai và phân tích cú pháp nó hai lần đơn giản là không cần thiết.
Bây giờ hơi quan tâm đến học thuật nhưng trước khi giới thiệu JSONvào Javascript, người ta có thể xâu chuỗi một chuỗi bằng cách kiểm tra nối tiếp các ký tự của nó và dấu gạch chéo ngược thoát dấu gạch chéo ngược, ít nhất một loại dấu ngoặc kép và mã điều khiển thoát unicode - câu hỏi đã đăng có thể bị thiếu phần về việc cần thoát các ký tự gạch chéo ngược cũng như các dấu ngoặc kép.