Stringa di escape nel contesto eval con JSON.stringify
Prima di tutto: so che ci sono molte domande relative alla fuga, ma finora non ho trovato una risposta generalmente funzionante. Supponiamo che io abbia questa semplice funzione giocattolo per dimostrazione:
function f(somePOJO) {
var s = eval("'" + JSON.stringify(somePOJO) + "';"); // for demonstration only
return JSON.parse(s);
}
const clone = f({a: 1, b: "c"});
Dato un oggetto letterale come {a: 1, b: "c"}(un POJO), fdovrebbe restituirne un "clone". (Nota che non uso davvero questo approccio per la clonazione o simili, e sono consapevole che evalè malvagio e anche che non è nemmeno necessario qui, è solo per dimostrazione del problema di fuga!)
Funziona bene, ma solo fintanto che i valori POJO non contengono un '. Ora ovviamente potrei sfuggire al JSON usando qualcosa di simile JSON.stringify(somePOJO).replace(/'/g, "\\'"). Funziona se i valori POJO contengono ', ma non se contengono \\'. E questo crea una spirale di fuga ...
C'è una soluzione a tutto questo?
Risposte
La funzione di escape per preservare una stringa JSON attraverso la valutazione della evalfunzione, il compilatore JavaScript in alcune circostanze o dalla JSON.parsefunzione è effettivamente JSON.stringify. Questo JSONmetodo stringerà felicemente i valori di stringa, non solo i tipi di dati degli oggetti.
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);
Il motivo per cui non fa parte della escape/encodeURI/encodeURIComponentfamiglia di funzioni è che si tratta di caratteri di escape per l'inclusione negli URL, mentre in questo caso si tratta di caratteri di escape per essere analizzati da un parser JavaScipt.
Nella maggior parte dei casi, in particolare per analizzare il testo JSON utilizzando JSON.parse, stringere il testo JSON una seconda volta e analizzarlo due volte non è semplicemente necessario.
Di interesse un po 'accademico ora, ma prima dell'introduzione di JSONin Javascript, si poteva stringere una stringa ispezionando in serie i suoi caratteri e la barra rovesciata che sfugge alle barre rovesciate, almeno un tipo di virgolette e codici di controllo che sfuggono all'unicode: la domanda pubblicata potrebbe non avere la parte sulla necessità di eseguire l'escape di caratteri backslash e virgolette.