Escape string dalam konteks eval dengan JSON.stringify

Nov 13 2020

Pertama-tama: Saya tahu bahwa ada banyak pertanyaan terkait dengan pelarian, tetapi sejauh ini saya tidak menemukan jawaban yang secara umum berfungsi. Katakanlah saya memiliki fungsi mainan sederhana ini untuk demonstrasi:

function f(somePOJO) {
  var s = eval("'" + JSON.stringify(somePOJO) + "';"); // for demonstration only
  return JSON.parse(s);
}
const clone = f({a: 1, b: "c"});

Diberikan sebuah objek literal seperti {a: 1, b: "c"}(sebuah POJO), fharus mengembalikan sebuah "tiruan" darinya. (Perhatikan bahwa saya tidak benar-benar menggunakan pendekatan ini untuk kloning atau serupa, dan saya sadar itu evaljahat dan bahkan tidak diperlukan di sini, ini hanya untuk menunjukkan masalah melarikan diri!)

Ini berfungsi dengan baik, tetapi hanya selama nilai POJO tidak mengandung a '. Sekarang tentu saja saya bisa melarikan diri dari JSON dengan menggunakan sesuatu seperti JSON.stringify(somePOJO).replace(/'/g, "\\'"). Ini berfungsi jika nilai POJO berisi ', tetapi tidak jika mengandung \\'. Dan ini menciptakan spiral pelarian ...

Apakah ada solusi untuk semua ini?

Jawaban

1 traktor Nov 13 2020 at 14:01

Fungsi escape untuk mempertahankan string JSON melalui evaluasi oleh evalfungsi tersebut, compiler JavaScript dalam beberapa keadaan atau JSON.parsefungsi sebenarnya JSON.stringify. JSONMetode ini akan dengan senang hati merangkai nilai string, bukan hanya tipe data objek.

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

Alasan mengapa ini bukan salah satu dari escape/encodeURI/encodeURIComponentkeluarga fungsi adalah bahwa ini untuk karakter pelolosan untuk dimasukkan dalam URL sedangkan kasus ini adalah tentang karakter pelolosan untuk diuraikan oleh pengurai JavaScipt.

Dalam kebanyakan kasus, terutama untuk mengurai teks JSON menggunakan JSON.parse, merangkai teks JSON untuk kedua kalinya dan menguraikannya dua kali tidak diperlukan.

Yang menjadi minat akademis sekarang tetapi sebelum pengenalan JSONke Javascript, seseorang dapat merangkai string dengan memeriksa karakternya secara serial dan garis miring terbalik dari garis miring terbalik, setidaknya satu jenis tanda kutip, dan kode kontrol pelolosan unicode - pertanyaan yang diposting mungkin kehilangan bagiannya tentang perlunya keluar dari karakter garis miring terbalik serta tanda kutip.