55 Stimmen

DecodeURIComponent vs unescape, was ist falsch mit unescape?

Beim Beantworten einer anderen Frage wurde mir klar, dass mein Wissen über Javascript/DOM etwas veraltet ist, da ich immer noch escape/unescape benutze, um die Inhalte von URL-Komponenten zu codieren, während es anscheinend besser ist, stattdessen encodeURIComponent/decodeURIComponent zu verwenden.

Was ich wissen möchte ist, was ist falsch an escape/unescape ? Es gibt vage Hinweise darauf, dass es irgendein Problem mit Unicode-Zeichen gibt, aber ich kann keine klare Erklärung finden.

Meine Web-Erfahrung ist ziemlich einseitig, fast alles, was ich gemacht habe, waren große Intranet-Anwendungen, die an den Internet Explorer gebunden waren. Dabei habe ich viel escape/unescape benutzt und die Anwendungen unterstützen Unicode seit vielen Jahren vollständig.

Also, welche Unicode-Probleme sollen escape/unescape haben? Hat jemand Testfälle, um die Probleme zu demonstrieren?

46voto

bobince Punkte 512550

Was ist falsch an escape/unescape?

Sie sind nicht "falsch" im eigentlichen Sinne, sondern ihr eigenes spezielles Zeichenformat, das ein bisschen wie die Codierung von URI-Parametern aussieht, es aber tatsächlich nicht ist. Insbesondere:

  • ‘+’ bedeutet Plus, nicht Leerzeichen
  • es gibt ein spezielles “%uNNNN”-Format zum Codieren von Unicode UTF-16 Codepunkten anstelle von Codierung von UTF-8 Bytes

Wenn Sie escape() verwenden, um URI-Parameterwerte zu erstellen, erhalten Sie falsche Ergebnisse für Zeichenketten, die ein Plus oder nicht-ASCII-Zeichen enthalten.

escape() könnte als interne JavaScript-spezifische Codierungsschema verwendet werden, beispielsweise zum Escapen von Cookie-Werten. Da jedoch alle Browser jetzt encodeURIComponent unterstützen (was ursprünglich nicht der Fall war), gibt es keinen Grund, escape anstelle davon zu verwenden.

Es gibt nur eine moderne Verwendung für escape/unescape, die ich kenne, und das ist als schnelle Möglichkeit, einen UTF-8-Encoder/Decoder zu implementieren, indem man die UTF-8-Verarbeitung in der URIComponent-Verarbeitung nutzt:

utf8bytes= unescape(encodeURIComponent(unicodecharacters));
unicodecharacters= decodeURIComponent(escape(utf8bytes));

11voto

ecmanaut Punkte 4813

escape funktioniert nur für Zeichen im Bereich von 0 bis 255 einschließlich (ISO-8859-1, was effektiv Unicode-Zeichen darstellt, die mit einem einzigen Byte darstellbar sind). (*)

encodeURIComponent funktioniert für alle Zeichenfolgen, die JavaScript darstellen kann (was den gesamten Bereich der grundlegenden mehrsprachigen Ebene von Unicode umfasst, d.h. Unicode-Zeichenpunkte von 0 bis 1.114.111 oder 0x10FFFF, die fast jedes heutige menschliche Schreibsystem abdecken).

Beide Funktionen erzeugen URL-sichere Zeichenfolgen, die nur Codepunkte von 0 bis 127 einschließlich (US-ASCII) verwenden. Letztere erreicht dies, indem sie die Zeichenfolge zunächst als UTF-8 kodiert und dann die %XX Hexkodierung anwendet, die von escape bekannt ist, für jeden Codepunkt, der nicht URL-sicher wäre.

Dies ist übrigens der Grund, warum Sie einen Zweifunktions-UTF-8-Encoder/-Decoder in JavaScript erstellen können, ohne Schleifen oder Müllgenerierung zu verwenden, indem Sie diese Grundfunktionen kombinieren, um alle bis auf die UTF-8-Verarbeitungsnebenwirkungen zu neutralisieren, da die Versionen von unescape und decodeURIComponent dasselbe rückgängig machen.

(*) Fußnote: Einige moderne Browser wie Google Chrome wurden angepasst, um %uXXXX für den über-255-Bereich von Zeichen zu produzieren, für die escape ursprünglich nicht definiert war, aber der Webserver-Support für das Dekodieren dieser Kodierung ist nicht so gut implementiert wie das Dekodieren der nach IETF-Standardisierten auf UTF-8 basierenden Kodierung.

9voto

sstur Punkte 1699

Ein weiteres "modernes" Beispiel, dem ich begegnet bin, ist das Parsen einer URI-codierten Zeichenfolge, die ungültige UTF8-Byte-Folgen enthalten kann. In bestimmten Fällen kann decodeURIComponent eine Ausnahme werfen. Es könnte notwendig sein, diese Ausnahme abzufangen und auf unescape zurückzugreifen.

Ein Beispiel wäre 'tür', kodiert als 't%FCr', was ich gesehen habe, wie es von Firefox erzeugt wird (wenn Zeichen in die Adressleiste nach dem ? eingefügt werden).

7voto

ucefkh Punkte 2509

Die beste Antwort ist diese, sie funktioniert online auf dieser Website http://meyerweb.com/eric/tools/dencoder/

function decode() {
    var obj = document.getElementById('dencoder');
    var encoded = obj.value;
    obj.value = decodeURIComponent(encoded.replace(/\+/g,  " "));
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X