JavaScript'te URL kodlansın mı?


2469

Bir URL'yi bir GET dizesine yerleştirilebilecek şekilde JavaScript kullanarak güvenli bir şekilde nasıl kodlarsınız?

var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;

myUrlDeğişkeni bu ikinci satırda kodlamanız gerektiğini varsayalım ?


22
İçine bakarak deneyin encodeURI () ve decodeURI () .
Zack The Human


1
Bu aracı burada kullanabilirsiniz: phillihp.com/toolz/url-encode-decode
phillihp

2
encodeURIComponent ()
Andrew

Yanıtlar:


2791

Yerleşik encodeURIComponent (str) ve encodeURI (str) işlevlerine bakın .
Sizin durumunuzda, bu işe yaramalıdır:

var myOtherUrl = 
       "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

12
@Cms'in verdiği açıklamayı eklemeye ne dersiniz? escapeaynı zamanda geçerli bir seçenektir.
hitautodestruct

11
@CMS'ye göre encodeURIURL kodlaması için gerçekten güvenli değildir.
Mart'ta 13

13
Gibi karakterleri izin vermez bütün URL'yi kodlamak için kastedilmektedir @AnaelFavre çünkü :, /, @Bu 2 yöntemler değiştirilebilir kullanılmayacaktır vb, doğru yöntemi kullanmak kodlama ne bilmesi gerekir.
Buu Nguyen


Bu sayfadaki başka bir cevapta belirtildiği gibi , bu site bu yöntemi kullanma nedenini güzelce detaylandırıyor
Brad Parks

1520

Üç seçeneğiniz var:

  • escape() kodlamaz: @*/+

  • encodeURI() kodlamaz: ~!@#$&*()=:/,;?+'

  • encodeURIComponent() kodlamaz: ~!*()'

Bir geçirmek istiyorsanız Ama senin durumunda, URL'yi bir içine GETdiğer sayfanın parametre, kullanmak gerekir escapeya da encodeURIComponentdeğil encodeURI.

Daha fazla tartışma için Yığın Taşması sorusuna bakınız. En iyi yöntem: escape veya encodeURI / encodeURIComponent .


76
Escape ile kullanılan karakter kodlaması değişkendir. UTF-8 kullanan encodeURI ve encodeURIComponent ile sopa.
erickson

6
Dikkatli ol. Bu kaçış, ASCII olmayan karakterleri Unicode kaçış dizilerine dönüştürür %uxxx.
opteronn

4
EncodeURIComponent kullanıyorum ve fark boru karakterleri kodlamak olmaz |
kevzettler

15
@kevzettler - bunu neden yapsın? Bir URI'de borular anlamsal öneme sahip değildir.
nickf

4
@GiovanniP: Almanca, Fransızca, Japonca, Çince, Arapça karakterlere GET veya POST yoluyla girdi ve tez parametrelerini geçiren kişiler.
Tseng

180

İle sopa encodeURIComponent(). İşlev encodeURI(), URL'lerde anlamsal öneme sahip birçok karakteri kodlamakla uğraşmaz (ör. "#", "?" Ve "&"). escape()kullanımdan kaldırılmıştır ve sunucuda kodlanmış boşluklar olarak yorumlanacak "+" karakterleri kodlamaya zahmet etmemektedir (ve burada başkaları tarafından belirtildiği gibi ASCII olmayan karakterleri düzgün şekilde URL kodlamamaktadır).

Ve başka yerler arasındaki farkınencodeURI()encodeURIComponent() güzel bir açıklaması var . Bir şeyi URI'nin bir bileşeni olarak (örneğin bir sorgu dizesi parametresi olarak) güvenli bir şekilde dahil edilebilecek şekilde kodlamak istiyorsanız, kullanmak istersiniz encodeURIComponent().


83

En iyi yanıt, sorgu dizesindeki (ve başka hiçbir yerde) değerlerencodeURIComponent üzerinde kullanmaktır .

Ancak, birçok API "" yerine "+" koymak istiyorum bulmak, bu yüzden aşağıdaki kullanmak zorunda buldum:

const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value

escapefarklı tarayıcılarda farklı şekilde uygulanır ve encodeURIbirçok karakteri kodlamaz (# ve hatta / gibi) - kırılmadan tam bir URI / URL'de kullanılmak üzere yapılır - bu süper yararlı veya güvenli değildir.

@Jochem'in aşağıda belirttiği gibi, encodeURIComponent()(her) klasör adında kullanmak isteyebilirsiniz , ancak bu API'ların +klasör adlarında istemediği herhangi bir nedenle bu yüzden düz eski encodeURIComponentharika çalışır.

Misal:

const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;

22
Lütfen ilk soru işaretinden sonra (URL'nin 'sorgu' kısmıdır)% 20 yerine + sembolleri kullanmanız gerektiğini unutmayın. Diyelim ki göz atmak istiyorum http://somedomain/this dir has spaces/info.php?a=this has also spaces. Şu biçime dönüştürülmelidir: http://somedomain/this%20dir%20has%spaces/info.php?a=this%20has%20also%20spacesancak birçok uygulama sorgu dizesindeki '% 20' yerine '+' ile değiştirilmesine izin verir. Bununla birlikte, URL'nin yol bölümünde '% 20' ile '+' +ifadesini değiştiremezsiniz; boşluk yerine dizininiz yoksa Bulunamadı hatasına neden olur .
Jochem Kuijpers

@Jochem Kuijpers, kesinlikle, bir dizine "+" koymazsınız. Bunu yalnızca sorgu parametresi değerlerinin kendilerine (veya gerekirse anahtarlara), URL'nin tamamına veya hatta tüm sorgu dizesine uygularım.
Ryan Taylor

Ben kodlama sonucu yerine değer yerine
njzk2

1
@ njzk2 maalesef encodeURIComponent('+')size verecekti %2B, bu yüzden iki normal ifade kullanmanız gerekecek ... Sanırım bu neden işe yarıyor, çünkü '+' are '' sonunda farklı kodlanmış.
Ryan Taylor

% 20'yi "+" ya çevirmek için hiçbir neden yoktur. ASCII alanı için geçerli kaçış dizisi, RFC 3986'da belirtilmeyen "+" değil,% 20'dir ( tools.ietf.org/html/rfc3986 ). 1990'larda "+" kullanıldı; artık kullanılmıyor ve sadece eski nedenlerle destekleniyor. Kullanma.
xhienne

40

JQuery kullanıyorsanız $.paramyöntem için gitmek istiyorum . URL, bir nesne eşleme alanlarını değerlerle kodlar; bu, okunması her değerde bir kaçış yöntemi çağırmaktan daha kolaydır.

$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1

Sağlanan örneğin yeterli olduğunu düşünüyorum. $ .Param hakkında daha fazla bilgiye ihtiyacınız varsa api.jquery.com/jquery.param
Maksym Kozlenko

Hemen hemen herkes jQuery kullanıyor ve encoreURIComponent yerine bununla gerçekten daha rahat hissediyorum
Cyril

12

encodeURIComponent () yolu bu.

var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

ANCAK php sürümünden küçük farklılıklar olduğunu urlencode()ve @CMS belirtildiği gibi, her karakter kodlamak olmayacağını unutmayın. Http://phpjs.org/functions/urlencode/ adresindeki çocuklar js ile eşdeğerdir phpencode():

function urlencode(str) {
  str = (str + '').toString();

  // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
  // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
  return encodeURIComponent(str)
    .replace('!', '%21')
    .replace('\'', '%27')
    .replace('(', '%28')
    .replace(')', '%29')
    .replace('*', '%2A')
    .replace('%20', '+');
}

10

Bir URL'yi daha önce söylendiği gibi kodlamak için iki işleviniz vardır:

encodeURI()

ve

encodeURIComponent()

Her ikisinin de var olmasının nedeni, birincinin URL'yi çok fazla şeyi kaçırma riskiyle korurken, ikincisi gereken her şeyi kodlamasıdır.

Birincisi ile yeni çıkmış URL'yi adres çubuğuna kopyalayabilirsiniz (örneğin). Ancak kaçan '' alanlarınız alan sınırlayıcılarını, '=' alan alanlarını ve değerlerini etkiler ve '+' lar boşluk gibi görünür. Ancak kaçtığınızın URL doğasını korumak istediğinizde basit veriler için bu işe yarar.

İkincisi, dizenizdeki hiçbir şeyin bir URL ile etkileşmediğinden emin olmak için yapmanız gereken her şeydir. Çeşitli önemsiz karakterlerin çıkışını engeller, böylece URL müdahale olmadan mümkün olduğunca insan tarafından okunabilir halde kalır. Bu şekilde kodlanan bir URL artık kaçmadan URL olarak çalışmaz.

Eğer zaman ayırabiliyorsanız, her zaman encodeURIComponent () öğesini kullanmak istersiniz - ad / değer çiftlerini eklemeden önce, sorgu dizesine eklemeden önce bu işlevi kullanarak hem adı hem de değeri kodlar.

EncodeURI () kullanmak için nedenlerle zor zamanlar yaşıyorum - Bunu daha akıllı insanlara bırakacağım.


5

Normal javascript ile denediğim benzer bir şey

function fixedEncodeURIComponent(str){
     return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}

5

Zarif yol

Benim düşünceme göre sorgu parametrelerini kodlamanın en zarif yolu, aşağıdaki gibi parametrelerle bir nesne oluşturmaktır.

const queryParams = { param1: 'value1', param2: 'value2' }

ve daha sonra şunu kullanarak kodlayın:

const queryString = new URLSearchParams(queryParams).toString()

bu cevapta belirtildiği gibi: https://stackoverflow.com/a/53171438/7284582


4

Çift kodlamayı önlemek için, kodlamadan önce URL'nin kodunu çözmek iyi bir fikirdir (örneğin, kullanıcı tarafından girilen URL'lerle ilgileniyorsanız, zaten kodlanmış olabilir).

Diyelim ki abc%20xyz 123girdi olarak varız (bir boşluk zaten kodlanmış):

encodeURI("abc%20xyz 123")            //   wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"

4

URL kodlaması nedir:

URL'nin içinde özel karakterler bulunduğunda bir URL kodlanmalıdır. Örneğin:

console.log(encodeURIComponent('?notEncoded=&+'));

Bu örnekte, dize dışındaki tüm karakterlerin notEncoded% işaretleriyle kodlandığını görebiliriz. URL kodlaması, % ile tüm özel karakterlerden kaçtığından yüzde kodlaması olarak da bilinir . Sonra bu% işaretinden sonra her özel karakterin benzersiz bir kodu vardır

URL kodlamasına neden ihtiyacımız var:

Bazı karakterlerin URL dizesinde özel bir değeri vardır. Örneğin,? karakteri bir sorgu dizesinin başlangıcını belirtir. Bir kaynağı web üzerinde başarılı bir şekilde bulmak için, bir karakterin dizenin bir parçası veya url yapısının bir parçası olarak ne zaman kastedildiğini ayırt etmek gerekir.

JS'de URL kodlamasını nasıl sağlayabiliriz:

JS, URL'leri kolayca kodlamak için kullanabileceğimiz bir dizi yardımcı program işlevi sunar. Bunlar iki uygun seçenektir:

  1. encodeURIComponent(): URI'nin bir bileşenini bağımsız değişken olarak alır ve kodlanmış URI dizesini döndürür.
  2. encodeURI(): Bir URI'yi bağımsız değişken olarak alır ve kodlanmış URI dizesini döndürür.

Örnek ve uyarılar:

URL'nin tamamını (şema dahil, ör. Https: //) içine geçirmediğinizi unutmayın encodeURIComponent(). Bu aslında işlevsel olmayan bir URL'ye dönüştürebilir. Örneğin:

// for a whole URI don't use encodeURIComponent it will transform
// the / characters and the URL won't fucntion properly
console.log(encodeURIComponent("http://www.random.com/specials&char.html"));

// instead use encodeURI for whole URL's
console.log(encodeURI("http://www.random.com/specials&char.html"));

Tüm URL'yi koyduğumuzda, encodeURIComponentkanatlı eğik çizgilerin (/) de özel karakterlere dönüştürüldüğünü görebiliriz. Bu, URL'nin artık düzgün çalışmamasına neden olacaktır.

Bu nedenle (adından da anlaşılacağı gibi) şunları kullanın:

  1. encodeURIComponent URL'nin kodlamak istediğiniz belirli bir bölümünde.
  2. encodeURI kodlamak istediğiniz URL'nin tamamı üzerinde.

3

Benim için hiçbir şey işe yaramadı. Tek gördüğüm giriş sayfasının HTML'si, kod 200 ile istemci tarafına geri geliyordu. giriş sayfasının metni).

Giriş denetleyicisine şu satırı ekledim:

Response.Headers["land"] = "login";

Global Ajax işleyicisinde bunu yaptım:

$(function () {
    var $document = $(document);
    $document.ajaxSuccess(function (e, response, request) {
        var land = response.getResponseHeader('land');
        var redrUrl = '/login?ReturnUrl=' + encodeURIComponent(window.location);
        if(land) {
            if (land.toString() === 'login') {
                window.location = redrUrl;
            }
        }
    });
});

Şimdi herhangi bir sorunum yok ve bu bir cazibe gibi çalışıyor.


2

URL Dizesini Kodla

    var url = $ ( konum ). attr ( 'href' ); // geçerli url'yi al // VEYA var url = 'klasör / dizin.html? param = # 23dd & noob = evet' ; // veya birini belirtin 
    
      

var encodedUrl = encodeURIComponent(url); console.log(encodedUrl); //outputs folder%2Findex.html%3Fparam%3D%2323dd%26noob%3Dyes for more info go http://www.sitepoint.com/jquery-decode-url-string

2

İşte olan CANLI DEMO arasında encodeURIComponent()ve decodeURIComponent()fonksiyonları inşa JS:

<!DOCTYPE html>
<html>
  <head>
    <style>
      textarea{
        width:30%;
        height:100px;
      }
    </style>
    <script>
      // encode string to base64
      function encode()
      {
        var txt = document.getElementById("txt1").value;
        var result = btoa(txt);
        document.getElementById("txt2").value = result;
      }
      // decode base64 back to original string
      function decode()
      {
        var txt = document.getElementById("txt3").value;
        var result = atob(txt);
        document.getElementById("txt4").value = result;
      }
    </script>
  </head>
  <body>
    <div>
      <textarea id="txt1">Some text to decode
      </textarea>
    </div>
    <div>
      <input type="button" id="btnencode" value="Encode" onClick="encode()"/>
    </div>
    <div>
      <textarea id="txt2">
      </textarea>
    </div>
    <br/>
    <div>
      <textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
      </textarea>
    </div>
    <div>
      <input type="button" id="btndecode" value="Decode" onClick="decode()"/>
    </div>
    <div>
      <textarea id="txt4">
      </textarea>
    </div>
  </body>
</html>

1

Esapi kitaplığını kullanabilir ve aşağıdaki işlevi kullanarak url'nizi kodlayabilirsiniz. İşlev, metin içeriğinin geri kalanı kodlanırken '/' kodlamasının kaybolmamasını sağlar:

function encodeUrl(url)
{
    String arr[] = url.split("/");
    String encodedUrl = "";
    for(int i = 0; i<arr.length; i++)
    {
        encodedUrl = encodedUrl + ESAPI.encoder().encodeForHTML(ESAPI.encoder().encodeForURL(arr[i]));
        if(i<arr.length-1) encodedUrl = encodedUrl + "/";
    }
    return url;
}

https://www.owasp.org/index.php/ESAPI_JavaScript_Readme


1

RFC 3986'yafixedEncodeURIComponent tam olarak uymak için işlevi kullanın :

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

1

encodeURIComponent()Doğrudan kullanmamalısınız .

RFC3986: Tekdüzen Kaynak Tanımlayıcısı (URI): Genel Sözdizimine bir göz atın

alt sınırlar = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Ayrılmış karakterlerin amacı, bir URI içindeki diğer verilerden ayırt edilebilen bir dizi sınırlayıcı karakter sağlamaktır.

RFC3986'daki URI tanımından ayrılmış olan bu karakterler kaçmaz encodeURIComponent().

MDN Web Belgeleri: encodeURIComponent ()

RFC 3986'ya (!, ', (,) Ve * ayıran) bağlı kalma konusunda daha katı olmak için, bu karakterlerin resmi URI sınırlayıcı kullanımları olmamasına rağmen, aşağıdakiler güvenle kullanılabilir:

MDN Web Dokümanları işlevini kullanın ...

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}
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.