it-swarm-eu.dev

Kdy byste měli místo úniku/kódování použít komponentu escape?

Při kódování řetězce dotazu, který má být odeslán na webový server - když používáte escape() a kdy používáte encodeURI() nebo encodeURIComponent():

Použít únik:

escape("% +&=");

OR

použít encodeURI ()/encodeURIComponent ()

encodeURI("http://www.google.com?var1=value1&var2=value2");

encodeURIComponent("var1=value1&var2=value2");
1323
Adam

uniknout()

escape() je definováno v sekci B.2.1.2 escape a úvodní text přílohy B říká:

... Všechny jazykové funkce a chování uvedené v této příloze mají jednu nebo více nežádoucích vlastností a v případě neexistence dědictví by bylo z této specifikace odstraněno. ...
... Programátoři by neměli používat nebo předpokládat existenci těchto vlastností a chování při psaní nového kódu ECMAScript.

Chování:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape

Speciální znaky jsou kódovány s výjimkou: @ * _ + -. /

Hexadecimální formulář pro znaky, jejichž hodnota kódové jednotky je 0xFF nebo méně, je dvoumístná úniková sekvence: %xx.

Pro znaky s větší kódovou jednotkou se používá čtyřmístný formát %uxxxx. Toto není povoleno v řetězci dotazu (jak je definováno v RFC3986 ):

query       = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

Znak procenta je povolen pouze v případě, že je přímo následován dvěma hexdigity, procenta následovaná znakem u není povolena.

encodeURI ()

Použijte funkci encodeURI, pokud chcete pracovní adresu URL. Proveďte tento hovor:

encodeURI("http://www.example.org/a file with spaces.html")

dostat:

http://www.example.org/a%20file%20with%20spaces.html

Nevolajte encodeURIComponent, protože by zničil adresu URL a vrátil se

http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html

encodeURIComponent ()

Použijte encodeURIComponent, když chcete kódovat hodnotu parametru URL.

var p1 = encodeURIComponent("http://example.org/?a=12&b=55")

Poté můžete vytvořit požadovanou adresu URL:

var url = "http://example.net/?param1=" + p1 + "&param2=99";

Získáte tuto úplnou adresu URL:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=99

Všimněte si, že encodeURIComponent neunikne znaku '. Běžnou chybou je použít k vytvoření atributů html, jako je href='MyUrl', které by mohly utrpět chybu při injekci. Pokud vytváříte html z řetězců, použijte buď " místo ' pro uvozovky atributů, nebo přidejte další vrstvu kódování (' lze kódovat jako% 27).

Další informace o tomto typu kódování naleznete na adrese: http://en.wikipedia.org/wiki/Percent-encoding

1847
Arne Evertsson

Rozdíl mezi encodeURI() a encodeURIComponent() je přesně 11 znaků kódovaných enkódemURIComponent, ale nikoli kódovánímURI:

Table with the ten differences between encodeURI and encodeURIComponent

Tuto tabulku jsem vytvořil snadno pomocí console.table v prohlížeči Google Chrome s tímto kódem:

var arr = [];
for(var i=0;i<256;i++) {
  var char=String.fromCharCode(i);
  if(encodeURI(char)!==encodeURIComponent(char)) {
    arr.Push({
      character:char,
      encodeURI:encodeURI(char),
      encodeURIComponent:encodeURIComponent(char)
    });
  }
}
console.table(arr);

411

Našel jsem tento článek poučný: Javascript Madness: Analýza dotazu na řetězec

Našel jsem to, když jsem se snažil undersand proč decodeURIComponent nebyl dekódovat '+' správně. Zde je výpis:

String:                         "A + B"
Expected Query String Encoding: "A+%2B+B"
escape("A + B") =               "A%20+%20B"     Wrong!
encodeURI("A + B") =            "A%20+%20B"     Wrong!
encodeURIComponent("A + B") =   "A%20%2B%20B"   Acceptable, but strange

Encoded String:                 "A+%2B+B"
Expected Decoding:              "A + B"
unescape("A+%2B+B") =           "A+++B"       Wrong!
decodeURI("A+%2B+B") =          "A+++B"       Wrong!
decodeURIComponent("A+%2B+B") = "A+++B"       Wrong!
43
Damien

encodeURIComponent nekóduje -_.!~*'(), což způsobuje problém při odesílání dat do php v XML řetězci.

Například:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Obecný únik s encodeURI
%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E

Vidíte, jednoduchá citace není zakódována Pro vyřešení problému jsem vytvořil dvě funkce pro řešení problému v mém projektu, pro kódování URL:

function encodeData(s:String):String{
    return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}

Pro dekódování adresy URL:

function decodeData(s:String):String{
    try{
        return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")"));
    }catch (e:Error) {
    }
    return "";
}
38

encodeURI () - funkce escape () je pro únik javascriptu, ne HTTP.

37
Daniel Papasian

Malá srovnávací tabulka Java vs. JavaScript vs. PHP.

1. Java URLEncoder.encode (using UTF8 charset)
2. JavaScript encodeURIComponent
3. JavaScript escape
4. PHP urlencode
5. PHP rawurlencode

char   Java JavaScript --PHP---
[ ]     +    %20  %20  +    %20
[!]     %21  !    %21  %21  %21
[*]     *    *    *    %2A  %2A
[']     %27  '    %27  %27  %27 
[(]     %28  (    %28  %28  %28
[)]     %29  )    %29  %29  %29
[;]     %3B  %3B  %3B  %3B  %3B
[:]     %3A  %3A  %3A  %3A  %3A
[@]     %40  %40  @    %40  %40
[&]     %26  %26  %26  %26  %26
[=]     %3D  %3D  %3D  %3D  %3D
[+]     %2B  %2B  +    %2B  %2B
[$]     %24  %24  %24  %24  %24
[,]     %2C  %2C  %2C  %2C  %2C
[/]     %2F  %2F  /    %2F  %2F
[?]     %3F  %3F  %3F  %3F  %3F
[#]     %23  %23  %23  %23  %23
[[]     %5B  %5B  %5B  %5B  %5B
[]]     %5D  %5D  %5D  %5D  %5D
----------------------------------------
[~]     %7E  ~    %7E  %7E  ~
[-]     -    -    -    -    -
[_]     _    _    _    _    _
[%]     %25  %25  %25  %25  %25
[\]     %5C  %5C  %5C  %5C  %5C
----------------------------------------
char  -Java-  --JavaScript--  -----PHP------
[ä]   %C3%A4  %C3%A4  %E4     %C3%A4  %C3%A4
[ф]   %D1%84  %D1%84  %u0444  %D1%84  %D1%84
16
30thh

Doporučuji nepoužívat jednu z těchto metod, jak je. Napište svou vlastní funkci, která dělá správnou věc.

MDN poskytl dobrý příklad kódování adresy URL uvedené níže.

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);

console.log(header); 
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"


function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            //  so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

11
Jerry Joseph

Nezapomeňte také, že všechny kódují různé sady znaků a vyberete ten, který potřebujete. encodeURI () zakóduje méně znaků než encodeURIComponent (), který kóduje méně (a také odlišných, k dannyp bodu) znaků než escape ().

10
Pseudo Masochist

Pro kódování javascriptu byly dány tři vestavěné funkce -

  1. escape () - nekóduje @*/+ Tato metoda je zastaralá po ECMA 3, takže je třeba se tomu vyhnout.

  2. encodeURI () - nekóduje [email protected]#$&*()=:/,;?+' Předpokládá se, že URI je úplné URI, takže nekóduje vyhrazené znaky, které mají v URI zvláštní význam. Tato metoda se používá, když je záměr převést kompletní URL namísto nějakého zvláštního segmentu URL. Příklad - encodeURI('http://stackoverflow.com'); dá - http://stackoverflow.com

  3. encodeURIComponent () -does nekóduje - _ . ! ~ * ' ( ) Tato funkce zakóduje komponentu Uniform Resource Identifier (URI) nahrazením každé instance určitých znaků jednou, dvěma, třemi nebo čtyřmi sekvencemi escape reprezentujícími kódování UTF-8. charakter. Tato metoda by měla být použita pro převod komponenty URL. Některý vstup uživatele musí být například připojen Příklad - encodeURI('http://stackoverflow.com'); Poskytne - http% 3A% 2F% 2Fstackoverflow.com

Toto kódování se provádí v UTF 8, tj. Znaky budou převedeny do formátu UTF-8. 

encodeURIComponent se liší od enkódování v tom, že kóduje vyhrazené znaky a číslo znaku # kódováníURI

6
Gaurav Tiwari

Zjistil jsem, že experimentování s různými metodami je dobrou kontrolou zdravého rozumu i po dobrém zvládnutí toho, jaké jsou jejich různá použití a možnosti.

Za tímto účelem jsem našel tyto webové stránky mimořádně užitečné pro potvrzení podezření, že něco dělám správně. Ukázalo se také, že je užitečné pro dekódování řetězec enkódu, který může být poměrně náročný na interpretaci. Skvělá záložka pro:

http://www.the-art-of-web.com/javascript/escape/

3
veeTrain

Mám tuto funkci ...

var escapeURIparam = function(url) {
    if (encodeURIComponent) url = encodeURIComponent(url);
    else if (encodeURI) url = encodeURI(url);
    else url = escape(url);
    url = url.replace(/\+/g, '%2B'); // Force the replacement of "+"
    return url;
};
1
molokoloco

Přijatá odpověď je dobrá. Prodloužení poslední části:

Všimněte si, že encodeURIComponent neunikne znaku. Běžným Bugem je použít ho k vytvoření atributů html, jako je href = 'MyUrl', která by mohla utrpět chybu při injekci. Pokud vytváříte html z řetězců , Použijte buď "namísto" pro uvozovky atributů, nebo přidejte další vrstvu kódování ("_________"), která může být kódována jako% 27.

Pokud chcete být na bezpečné straně, procent kódování bezvýhradných znaků by mělo být také kódováno. 

Tuto metodu můžete použít k úniku (zdroj Mozilla )

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

// fixedEncodeURIComponent("'") --> "%27"
1
Michael

Moderní přepsání odpovědi uživatele @ johann-echavarria:

console.log(
    Array(256)
        .fill()
        .map((ignore, i) => String.fromCharCode(i))
        .filter(
            (char) =>
                encodeURI(char) !== encodeURIComponent(char)
                    ? {
                          character: char,
                          encodeURI: encodeURI(char),
                          encodeURIComponent: encodeURIComponent(char)
                      }
                    : false
        )
)

Nebo pokud můžete použít tabulku, nahraďte console.log pomocí console.table (pro hezčí výstup).

1
ryanpcmcquen

Inspirován Johannovým stolem , Rozhodl jsem se rozšířit stůl. Chtěl jsem zjistit, které znaky ASCII jsou zakódovány.

 screenshot of console.table

var ascii = " !\"#$%&'()*+,-./0123456789:;<=>[email protected][\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

var encoded = [];

ascii.split("").forEach(function (char) {
    var obj = { char };
    if (char != encodeURI(char))
        obj.encodeURI = encodeURI(char);
    if (char != encodeURIComponent(char))
        obj.encodeURIComponent = encodeURIComponent(char);
    if (obj.encodeURI || obj.encodeURIComponent)
        encoded.Push(obj);
});

console.table(encoded);

Tabulka zobrazuje pouze zakódované znaky. Prázdné buňky znamenají, že originál a kódované znaky jsou stejné.


Abych byl navíc, přidávám další tabulku pro urlencode() vs rawurlencode() . Jediný rozdíl se zdá být kódování znaku prostoru.

 screenshot of console.table

<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>[email protected][\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 1);
$encoded = [];
foreach ($ascii as $char) {
    $obj = ["char" => $char];
    if ($char != urlencode($char))
        $obj["urlencode"] = urlencode($char);
    if ($char != rawurlencode($char))
        $obj["rawurlencode"] = rawurlencode($char);
    if (isset($obj["rawurlencode"]) || isset($obj["rawurlencode"]))
        $encoded[] = $obj;
}
echo "var encoded = " . json_encode($encoded) . ";";
?>
console.table(encoded);
</script>
0
akinuri