Ne zaman encodeURI / encodeURIComponent yerine escape kullanmanız gerekir?


1392

Kullanmak ne zaman - bir sorgu dizesi kodlayan zaman bir web sunucusuna gönderilecek escape()ve ne zaman kullanmak encodeURI()veya encodeURIComponent():

Kaçış kullan:

escape("% +&=");

VEYA

encodeURI () / encodeURIComponent () kullanın

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

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

111
Dikkat Buna değer işaret var encodeURIComponent("var1=value1&var2=value2")olduğunu değil , tipik kullanım şeklidir. Bu örnek =ve &muhtemelen kodlanmış olanı kodlayacaktır ! encodeURIComponentgenellikle her bir anahtar / değer çiftindeki (her birinden sonraki kısım =) değere ayrı ayrı uygulanır .
Timothy Shields

3
anahtara bir şey yapman gerekiyor mu? İçinde bir = varsa ne olur? (bu mümkün mü?)
Mala

3
@Mala Genel olarak web programlamasında hala yeniyim, ancak sınırlı deneyimimde kullandığım anahtar ve değeri ayrı ayrı kodlamak, '=' kalmasını sağlamak: var params = encodeURIComponent(key) + '=' + encodeURIComponent(value);- Belki başka biri daha iyi bir yol biliyor.
nedshares

1
@nedshares Bununla oynuyordum, ama anlayabildiğim kadarıyla anahtar kodlanmış gibi görünmüyor ... en azından aynı şekilde değil. Belki anahtarda bir = olması spec'e karşı mıdır?
Mala

1
Ayrıca, son JavaScript uygulamalarının URL'leri ve sorgu dizelerini değiştirmek için daha üst düzey arayüzler URL ve URLSearchParams sağladığını belirtmek gerekir .
Bart Robinson

Yanıtlar:


1914

kaçış()

Kullanma! escape()bölüm B.2.1.2 kaçışında tanımlanmıştır ve Ek B'nin giriş metni şöyle diyor:

... Bu ekte belirtilen tüm dil özellikleri ve davranışları bir veya daha fazla istenmeyen özelliğe sahiptir ve eski kullanım yokluğunda bu spesifikasyondan kaldırılacaktır. ...
... Programcılar yeni ECMAScript kodu yazarken bu özellikleri ve davranışları kullanmamalı veya varlığını varsaymamalıdır ....

Davranış:

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

Özel karakterler aşağıdakiler hariç kodlanmıştır: @ * _ + -. /

Kod birim değer 0XFF ya da daha az olan karakterlerin, onaltılı bir şekilde, iki basamaklı bir kaçış dizisidir: %xx.

Daha büyük kod birimine sahip karakterler için dört basamaklı biçim %uxxxxkullanılır. Bir sorgu dizesinde buna izin verilmez ( RFC3986'da tanımlandığı gibi ):

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

Yüzde işaretine yalnızca doğrudan iki onaltılık izlenirse uizin verilir , yüzde izine izin verilmez.

encodeURI ()

Çalışan bir URL istediğinizde encodeURI kullanın. Bu aramayı yapın:

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

almak:

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

URL'yi yok edip geri döneceği için encodeURIComponent öğesini çağırma

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

encodeURIComponent ()

Bir URL parametresinin değerini kodlamak istediğinizde encodeURIComponent kullanın.

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

Ardından, ihtiyacınız olan URL'yi oluşturabilirsiniz:

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

Ve bu tam URL'yi alacaksınız:

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

EncodeURIComponent öğesinin 'karakterden kaçmadığını unutmayın . Yaygın bir hata, href='MyUrl'bir enjeksiyon hatası çekebilecek gibi html nitelikleri oluşturmak için kullanmaktır . Dizelerden html oluşturuyorsanız öznitelik tırnakları "yerine kullanın 'veya fazladan bir kodlama katmanı ekleyin ( '% 27 olarak kodlanabilir).

Bu tür kodlama hakkında daha fazla bilgi için şunları kontrol edebilirsiniz: http://en.wikipedia.org/wiki/Percent-encoding


31
@Francois, alıcı sunucuya bağlı olarak, kaçışın üst ASCII veya ASCII olmayan karakterleri nasıl kodladığını düzgün şekilde çözemeyebilir: âầẩẫấậêềểễếệ Örneğin, Python'un FieldStorage sınıfı, kodlanmış güle kaçış durumunda yukarıdaki dizginin kodunu düzgün şekilde çözemez.
Ray

22
@Francois escape (), harfler, rakamlar ve *@-_+./ dışında daha düşük 128 ASCII karakterini kodlarken unescape (), escape () işlevinin tersidir. Anlayabildiğim kadarıyla, URL'leri kodlamak için tasarlanmış eski işlevlerdir ve hala geriye dönük uyumluluk için uygulanmaktadır. Genellikle, kendileri için tasarlanmış bir uygulama / web hizmeti / vb.
Anthony DiSanti

3
Tabii ki bir URL'yi URI bileşeni olarak geçirmeye çalışmıyorsanız, bu durumda encodeURIComponent çağırın.
tom

4
Neden tek alıntıyı yapmıyor?
Eric

11
@Eric Tek tırnak işaretlemez, çünkü tek tırnak bir URI içinde gerçekleşmesi tamamen geçerli bir karakterdir ( RFC-3986 ). Tek tırnak geçerli bir karakter olmayan bir URI HTML içine katıştırdığınızda, sorun oluşur . URI'ları da (yerini alacak olan "HTML kodlu" olmalıdır ki, o zaman şu 'ile 'bir HTML belgesi içine koyulmadan önce).
Lee

441

Arasındaki fark encodeURI()ve encodeURIComponent()encodeURIComponent tarafından değil encodeURI tarafından kodlanan 11 karakter tam olarak şunlardır:

EncodeURI ve encodeURIComponent arasındaki on fark içeren tablo

Bu tabloyu Google Chrome'da console.table ile bu kodla kolayca oluşturdum :

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


Bu tarayıcı bağımlı değil mi?
Pacerier

4
@bladnman encodeURI ve encodeURIComponent tüm büyük tarayıcılarda bu şekilde çalışmalıdır. Chrome ve Firefox'ta yukarıdaki kodu her ikisi de destek konsolu olarak test edebilirsiniz. Tablo. Diğer tarayıcılarda (Firefox ve Chrome dahil) aşağıdaki kodu kullanabilirsiniz:var arr=[]; for(var i=0;i<256;i++){var char=String.fromCharCode(i); if(encodeURI(char)!==encodeURIComponent(char)) console.log("character: "+char + " | encodeURI: " +encodeURI(char) + " |encodeURIComponent: " + encodeURIComponent(char) ) }
Johann Echavarria

1
@Pacerier :)
Johann Echavarria

@ Orijinal özellik çok belirsiz olmadığı sürece Pacer çeşitli tarayıcılarda aynı olmalıdır ... ayrıca bkz. Stackoverflow.com/questions/4407599/…
Christophe Roussy

2
BU BİR KEZ ZAMANIN ÜSTÜNLENMESİ GEREKİR! Ne yazık ki sadece bir kez yükselebilir.
Ramazan Polat

46

Bu makaleyi aydınlatıcı buldum: Javascript Madness: Query String Parsing

DecodeURIComponent'in neden '+' kodunu doğru çözmediğini anlamaya çalışırken buldum. İşte bir özü:

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!

11
Bağlantı verdiğiniz makale çok saçmalık içeriyor. Bana öyle geliyor ki, yazarın kendisi işlevlerin ne için doğru kullanıldığını anlamadı ...
Christoph

2
@Christoph Her şey benim için makul görünüyor. Özellikle, encodeURIsadece oldukça belirsiz bir uç durumda yararlı olduğunu ve gerçekten var olması gerekmediğini kabul ediyorum . Onunla bazı görüş farklılıklarım var, ama orada yanlış veya aptalca bir şey görmüyorum. Sizce saçmalık tam olarak nedir?
Mark Amery

1
enctypeÖznitelik FORMelemanı belirttiği içerik türü sunucusuna sunulmak üzere form verilerini setini kodlamak için kullanılan. application / x-www-form-urlencoded Bu, varsayılan içerik türüdür. Bu içerik türüyle gönderilen formlar aşağıdaki gibi kodlanmalıdır: [...] Boşluk karakterleri `` + 'ile değiştirilir ve [...] Alfasayısal olmayan karakterler `` HH' 'ile değiştirilir, [...] Referans: HTML4 Sepc
cychoi

2
encodeURIComponent ('A + B'). değiştirin (/ \% 20 / g, '+') + '\ n' + decodeURIComponent ("A +% 2B + B". değiştirin (/ \ + / g, '% 20' ));
Zlatin Zlatev

39

encodeURIComponent kodlamıyor -_.!~*'(), bu da xml dizgisinde php'ye veri göndermede soruna neden oluyor.

Örneğin:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

İle genel kaçış 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

Gördüğünüz gibi, tek tırnak kodlanmamış. Sorunu çözmek için Kodlama URL'si için projemdeki sorunu çözmek için iki işlev oluşturdum:

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

Kod Çözme URL'si için:

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

5
Ayrıca% 23 olan # (pound / hash / number) işaretini yapmaz.
xr280xr

1
@ xr280xr Ne demek istiyorsun? encodeURIComponent # #% 23 kodlar (belki 2014 yılında yoktu?)
David Balažic

38

encodeURI () - escape () işlevi HTTP için değil, javascript çıkış için kullanılır.


Eğer böyle bir url varsa: var url = "http://kuler-api.adobe.com/rss/get.cfm?startIndex=0&itemsPerPage=20&timeSpan=0&listType=rating"... Ve ben Google Ajax API ile erişmek istiyorum, şöyle: var gurl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q=" + url;... sonra kullanmak zorunda escape(url). encodeURI(url)göründüğü gibi parametrelerle çalışmaz.
Lance Pollard

15
u ecnodeURIComponent (url) kullanmalısınız
Ustaman Sangat

2
Tüm 3 işlevin kendi sorunları vardır. İşi yapan kendi işlevinizi oluşturmak daha iyidir.
Jerry Joseph

17

Küçük karşılaştırma tablosu Java'ya karşı JavaScript'e karşı 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

12

Bu yöntemlerden birini olduğu gibi kullanmamanızı tavsiye ederim. Doğru olanı yapan kendi fonksiyonunuzu yazın.

MDN, aşağıda gösterilen url kodlamasına iyi bir örnek vermiştir.

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


1
ne harika bir cevap (eğer krom kenarı ve firefox arasında herhangi bir hata yapmadan
uyumluysa

10

Ayrıca hepsinin farklı karakter kümelerini kodladığını ve ihtiyacınız olanı uygun şekilde seçtiğini unutmayın. encodeURI (), encodeURIComponent () öğesinden daha az karakter kodlar, bu da kaçış () öğesinden daha az (ve dannyp'nin noktasından farklı) karakterleri kodlar.


8

Javascript kodlamak amacıyla üç dahili fonksiyon verdi -

  1. escape()- @*/+ kodlamıyor ECMA 3'ten sonra bu yöntem kullanımdan kaldırılmıştır, bu nedenle bundan kaçınılmalıdır.

  2. encodeURI()- ~!@#$&*()=:/,;?+' kodlamıyor URI'nin tam bir URI olduğunu varsayar, bu nedenle URI'de özel anlamı olan ayrılmış karakterleri kodlamaz. Bu yöntem, URL'nin bazı özel segmentleri yerine tam URL'yi dönüştürmek olduğunda kullanılır. Örnek - encodeURI('http://stackoverflow.com'); verecek - http://stackoverflow.com

  3. encodeURIComponent()- kodlamıyor - _ . ! ~ * ' ( ) Bu işlev, belirli karakterlerin her bir örneğini karakterin UTF-8 kodlamasını temsil eden bir, iki, üç veya dört kaçış dizisiyle değiştirerek Tekdüzen Kaynak Tanımlayıcısı (URI) bileşenini kodlar. Bu yöntem URL'nin bir bileşenini dönüştürmek için kullanılmalıdır. Örneğin, bazı kullanıcı girişlerinin eklenmesi gerekir Örnek - encodeURIComponent('http://stackoverflow.com'); -% http: 3A% 2F% 2Fstackoverflow.com

Tüm bu kodlama UTF 8'de gerçekleştirilir, yani karakterler UTF-8 biçiminde dönüştürülecektir.

encodeURIComponent, encodeURI öğesinden ayrılmış karakterleri ve encodeURI sayı işaretini kodlaması bakımından farklıdır


3

Çeşitli yöntemlerle denemenin, çeşitli kullanımlarının ve yeteneklerinin ne olduğunu iyi bir şekilde ele geçirdikten sonra bile iyi bir sağlık kontrolü olduğunu buldum.

Bu amaçla doğru bir şey yaptığımdan şüphelerimi doğrulamak için bu web sitesini son derece yararlı buldum . Ayrıca yorumlanması oldukça zor olan bir encodeURIComponent' dizesinin kodunun çözülmesinde de yararlı olduğu kanıtlanmıştır. Sahip olmak için harika bir yer imi:

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


2

Kabul edilen cevap iyidir. Son kısmı genişletmek için:

EncodeURIComponent öğesinin 'karakterinden çıkmadığını unutmayın. Sık karşılaşılan bir hata, bir enjeksiyon hatası yaşayabilecek href = 'MyUrl' gibi html öznitelikleri oluşturmak için kullanmaktır. Dizelerden html oluşturuyorsanız, öznitelik tırnak işaretleri için 'yerine' kullanın ya da fazladan bir kodlama katmanı ekleyin ('% 27 olarak kodlanabilir).

Güvenli tarafta olmak istiyorsanız, kaydedilmemiş karakterleri kodlama yüzdesi de kodlanmalıdır.

Onlardan kaçmak için bu yöntemi kullanabilirsiniz (kaynak Mozilla )

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

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

2

@ Johann-echavarria'nın cevabının modern yeniden yazımı:

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

Eğer bir tablo kullanabilirsiniz Veya değiştirin console.logile console.table(daha güzel çıkışı için).


2

Johann'ın masasından esinlenerek masayı uzatmaya karar verdim. Hangi ASCII karakterlerinin kodlandığını görmek istedim.

console.table ekran görüntüsü

Tablo yalnızca kodlanmış karakterleri gösterir. Boş hücreler, orijinal ve kodlanan karakterlerin aynı olduğu anlamına gelir.


Sadece ekstra olmak için, urlencode()vs için başka bir tablo ekliyorum rawurlencode(). Tek fark, boşluk karakterinin kodlanması gibi görünüyor.

console.table ekran görüntüsü

<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`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>

1

Bu işleve sahibim ...

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

4
@ChristianVielma escape () kullanımdan kaldırıldı, ancak asla w3schools.com adresine başvurmayın. bkz w3fools.com
Jerry Joseph

4
@Christian Vielma - Bazı bulmak referans malzemesini de W3Schools'da olmaya az tartışmalı ve kullanışlı . Herkes W3Schools'a hiç başvurulmaması gerektiğini kabul etmez.
DavidRR

2
W3Schools kötü bir rap alır. Tabii ki her zaman doğru değildir, ama sonra tekrar düpedüz yanlış olan bir blog yazısı ile karşılaştım. Benim için bazen sadece bazı terminolojiyi öğrenmek için harika bir başlangıç ​​noktası ve sonra diğer kaynaklarla biraz daha derinlere dalıyoruz. En önemlisi, bu tür şeyler söz konusu olduğunda tek bir kaynağın İncil olmaması gerektiğidir.
ryandlf

Görünüşe göre @molokoloco bu işlevi, var encodeURIolmayan ancak escapevar olan sürümlere bir geri dönüş olarak yazdı .
SOFe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.