pengembangan-web-mp-pd.com

Kapan Anda seharusnya menggunakan escape daripada encodeURI/encodeURICon?

Saat menyandikan string kueri untuk dikirim ke server web - kapan Anda menggunakan escape() dan kapan Anda menggunakan encodeURI() atau encodeURIComponent():

Gunakan melarikan diri:

escape("% +&=");

OR

gunakan encodeURI ()/encodeURIComponent ()

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

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

melarikan diri()

Jangan menggunakannya! escape() didefinisikan di bagian B.2.1.2 melarikan diri dan teks pengantar Lampiran B mengatakan:

... Semua fitur bahasa dan perilaku yang ditentukan dalam lampiran ini memiliki satu atau lebih karakteristik yang tidak diinginkan dan tanpa adanya penggunaan sebelumnya akan dihapus dari spesifikasi ini. ...
... Pemrogram tidak boleh menggunakan atau menganggap keberadaan fitur dan perilaku ini saat menulis kode skrip ECMAS baru ....

Tingkah laku:

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

Karakter khusus dikodekan dengan pengecualian: @ * _ + -. /

Bentuk heksadesimal untuk karakter, yang nilai unit kode-nya 0xFF atau kurang, adalah urutan pelarian dua digit: %xx.

Untuk karakter dengan unit kode yang lebih besar, format empat digit %uxxxx digunakan. Ini tidak diizinkan dalam string kueri (sebagaimana didefinisikan dalam RFC3986 ):

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

Tanda persen hanya dibolehkan jika diikuti langsung oleh dua hexdigits, persen diikuti oleh u tidak diperbolehkan.

encodeURI ()

Gunakan encodeURI saat Anda menginginkan URL yang berfungsi. Lakukan panggilan ini:

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

mendapatkan:

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

Jangan panggil komponen encodeURIC karena akan menghancurkan URL dan kembali

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

komponen encodeURIC ()

Gunakan komponen encodeURIC ketika Anda ingin menyandikan nilai parameter URL.

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

Maka Anda dapat membuat URL yang Anda butuhkan:

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

Dan Anda akan mendapatkan URL lengkap ini:

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

Perhatikan bahwa komponen encodeURIC tidak lepas dari karakter '. Bug umum adalah menggunakannya untuk membuat atribut html seperti href='MyUrl', yang dapat mengalami bug injeksi. Jika Anda membuat html dari string, gunakan " alih-alih ' untuk kutipan atribut, atau tambahkan lapisan pengkodean tambahan (' dapat dikodekan sebagai% 27).

Untuk informasi lebih lanjut tentang jenis pengkodean ini, Anda dapat memeriksa: http://en.wikipedia.org/wiki/Percent-encoding

1847
Arne Evertsson

Perbedaan antara encodeURI() dan encodeURIComponent() persis 11 karakter yang dikodekan oleh encodeURICon tetapi tidak oleh encodeURI:

Table with the ten differences between encodeURI and encodeURIComponent

Saya membuat tabel ini dengan mudah dengan console.table di Google Chrome dengan kode ini:

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

Saya menemukan artikel ini mencerahkan: Javascript Madness: Query String Parsing

Saya menemukannya ketika saya mencoba untuk menjelaskan mengapa komponen decodeURIC tidak mendekode '+' dengan benar. Ini ekstraknya:

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 tidak menyandikan -_.!~*'(), menyebabkan masalah dalam memposting data ke php dalam string xml.

Sebagai contoh:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Pelarian umum dengan 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

Anda dapat melihat, kutipan tunggal tidak disandikan . Untuk menyelesaikan masalah, saya membuat dua fungsi untuk menyelesaikan masalah di proyek saya, untuk URL Pengkodean:

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

Untuk URL Dekode:

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 () - fungsi escape () adalah untuk meloloskan javascript, bukan HTTP.

37
Daniel Papasian

Tabel perbandingan kecil 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

Saya sarankan untuk tidak menggunakan salah satu metode tersebut apa adanya. Tulis fungsi Anda sendiri yang melakukan hal yang benar.

MDN telah memberikan contoh yang baik tentang penyandian url yang ditunjukkan di bawah ini.

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

Juga ingat bahwa mereka semua menyandikan set karakter yang berbeda, dan pilih yang Anda butuhkan dengan tepat. encodeURI () mengkodekan karakter lebih sedikit daripada encodeURIComponent (), yang mengkodekan lebih sedikit (dan juga berbeda, ke titik dannyp's) karakter daripada escape ().

10
Pseudo Masochist

Untuk tujuan pengkodean javascript telah memberikan tiga fungsi bawaan -

  1. escape () - tidak menyandikan @*/+ Metode ini sudah usang setelah ECMA 3 sehingga harus dihindari.

  2. encodeURI () - tidak menyandikan [email protected]#$&*()=:/,;?+'Ini mengasumsikan bahwa URI adalah URI lengkap, jadi jangan menyandikan karakter yang dipesan yang memiliki arti khusus dalam URI . Metode ini digunakan ketika maksudnya adalah untuk mengkonversi lengkap URL alih-alih beberapa segmen khusus URL . Contoh - encodeURI('http://stackoverflow.com'); Akan memberikan - http://stackoverflow.com

  3. encodeURIComponent () -tidak melakukan encode - _ . ! ~ * ' ( ) Fungsi ini mengkodekan komponen Uniform Resource Identifier (URI) dengan mengganti setiap instance karakter tertentu dengan satu, dua, tiga, atau empat sekuens escape yang mewakili pengkodean karakter UTF-8. Metode ini harus digunakan untuk mengonversi komponen URL. Misalnya beberapa input pengguna perlu ditambahkan Contoh - encodeURI('http://stackoverflow.com');.__ akan memberikan - http% 3A% 2F% 2Fstackoverflow.com

Semua pengkodean ini dilakukan dalam UTF 8 yaitu karakter akan dikonversi dalam format UTF-8. 

komponen encodeURIC berbeda dari encodeURI dalam hal itu mengkodekan karakter yang dilindungi undang-undang dan tanda Nomor # dari encodeURI

6
Gaurav Tiwari

Saya telah menemukan bahwa bereksperimen dengan berbagai metode adalah pemeriksaan kewarasan yang baik bahkan setelah memiliki pegangan yang baik tentang berbagai kegunaan dan kemampuan mereka.

Menjelang akhir itu saya telah menemukan situs web ini sangat berguna untuk mengkonfirmasi kecurigaan saya bahwa saya melakukan sesuatu dengan tepat. Ia juga terbukti berguna untuk mendekode string yang dikompilasi oleh encodeURIC yang agak sulit ditafsirkan. Bookmark yang bagus untuk dimiliki:

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

3
veeTrain

Saya memiliki fungsi ini ...

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

Jawaban yang diterima adalah baik ..__ Untuk memperluas pada bagian terakhir:

Perhatikan bahwa komponen encodeURIC tidak lepas dari karakter '. Biasa bug adalah menggunakannya untuk membuat atribut html seperti href = 'MyUrl', yang dapat menderita bug injeksi. Jika Anda membuat html dari strings, bisa menggunakan "bukan 'untuk kutipan atribut, atau menambahkan .__ lapisan tambahan pengkodean (' dapat dikodekan sebagai% 27).

Jika Anda ingin berada di sisi yang aman, persen penyandian karakter tanpa syarat juga harus disandikan. 

Anda dapat menggunakan metode ini untuk menghindarinya (sumber Mozilla )

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

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

Penulisan ulang modern jawaban @ 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
        )
)

Atau jika Anda bisa menggunakan tabel, ganti console.log dengan console.table (untuk hasil yang lebih cantik).

1
ryanpcmcquen

Terinspirasi oleh tabel Johann , saya telah memutuskan untuk memperpanjang meja. Saya ingin melihat karakter ASCII mana yang disandikan.

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

Tabel hanya menunjukkan karakter yang disandikan. Sel kosong berarti bahwa karakter asli dan yang disandikan adalah sama.


Sebagai tambahan, saya menambahkan tabel lain untuk urlencode() vs rawurlencode() . Satu-satunya perbedaan tampaknya adalah pengkodean karakter ruang.

 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