Czy powinienem używać encodeURI lub encodeURIComponent do kodowania adresów URL?


281

Której z tych dwóch metod należy używać do kodowania adresów URL?



13
Jedną z głównych różnic jest to, że encodeURInie będzie kodować, /więc: encodeURIComponent("ac/dc")=> ac%2Fdci encodeURI("ac/dc")=>ac/dc

Może to być pomocne: "encodeURIComponent() and encodeURI() encode a URI by replacing URL reserved characters with their UTF-8 encoding....They differ because encodeURI does not encode queryString or hash values...URLs do not allow many special characters, like spaces or slashes. However these special characters are part of life, so URL encoding was invented." Źródło
użytkownik1063287,

Zobacz także konkretną sekcję zatytułowaną encodeURIComponent differs from encodeURI as follows: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1063287

Odpowiedzi:


324

To zależy od tego, co naprawdę chcesz zrobić.

encodeURI zakłada, że ​​wejście jest kompletnym identyfikatorem URI, który może zawierać pewne znaki wymagające kodowania.

encodeURIComponent koduje wszystko o specjalnym znaczeniu, więc używasz go dla składników URI takich jak

var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);

108

Jeśli kodujesz ciąg znaków w celu wstawienia do komponentu URL (parametr querystring), powinieneś wywołać encodeURIComponent.

Jeśli kodujesz istniejący adres URL, zadzwoń encodeURI.


1
Jeśli używam ajax, jak mogę zdekodować adres URL, który jest przekazywany do php?
Aditya Shukla

6
Ty nie. Serwer robi to automatycznie.
Quentin

@Aditya: To zależy od tego, co robisz.
SLaks,

@slaks. Przekazuję parametry przez get, więc chcę je odzyskać w php.
Aditya Shukla

2
Dobrze. Mógłbym mówić nieco pospiesznie, kiedy powiedziałem, że serwer to zrobi, ale jakakolwiek biblioteka, której użyjesz do odczytu danych formularza, zajmie się tym.
Quentin

46

xkr.us ma świetną dyskusję z przykładami. Cytując ich podsumowanie:

Metoda escape () nie koduje znaku +, który jest interpretowany jako spacja po stronie serwera, jak również generowany przez formularze ze spacjami w swoich polach. Z powodu tego niedociągnięcia i faktu, że ta funkcja nie obsługuje poprawnie znaków spoza ASCII, należy unikać użycia escape (), gdy tylko jest to możliwe. Najlepszą alternatywą jest zwykle encodeURIComponent ().

Escape () nie koduje: @ * / +

Zastosowanie metody encodeURI () jest nieco bardziej wyspecjalizowane niż escape () w tym sensie, że koduje dla identyfikatorów URI w przeciwieństwie do kwerendy, która jest częścią adresu URL. Tej metody należy użyć, gdy trzeba zakodować ciąg znaków dla dowolnego zasobu korzystającego z identyfikatorów URI i potrzebujących pewnych znaków, aby pozostały niezakodowane. Zauważ, że ta metoda nie koduje znaku „, ponieważ jest to prawidłowy znak w identyfikatorach URI.

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

Na koniec należy zastosować metodę encodeURIComponent () w większości przypadków podczas kodowania pojedynczego składnika identyfikatora URI. Ta metoda koduje niektóre znaki, które normalnie byłyby rozpoznawane jako znaki specjalne dla identyfikatorów URI, aby można było uwzględnić wiele składników. Zauważ, że ta metoda nie koduje znaku „, ponieważ jest to prawidłowy znak w identyfikatorach URI.

encodeURIComponent () nie koduje: ~! * () '


Ostatnio się nauczyłem. Serwery TOMCAT 9 są bardziej szczegółowe na temat tego, co możesz wysłać na adres URL. Metoda encodeURIComponent () wydaje się działać lepiej w przypadkach, gdy masz „spacje” w tym, co musisz zakodować. Tomcat 8 nie dbał o to, ale 9 jest o wiele bardziej szczegółowe.
Aggie Jon z 87

Innymi słowy, encodeURIkończy się niepowodzeniem, jeśli próbujesz przekonwertować nazwę pliku na adres URL, a nazwa pliku zawiera się #w nim
gman

17

Oto podsumowanie.

  1. Escape () nie koduje @ * _ + -. /

    Nie używaj tego.

  2. encodeURI () nie koduje AZ az 0-9; , /? : @ & = + $ - _. ! ~ * '() #

    Użyj go, gdy podany przez Ciebie adres jest kompletnym adresem URL, takim jak „ https://searchexample.com/search?q=wiki

  3. encodeURIComponent () nie koduje AZ az 0-9 - _. ! ~ * '() Użyj go, gdy dane wejściowe są częścią pełnego adresu URL, np const queryStr = encodeURIComponent(someString)

1
To doskonała odpowiedź, ponieważ dokładnie mówi, co robią. Nadal jednak mam pytanie, z którego i kiedy powinienem skorzystać. Co się stanie, jeśli mój składnik URI to pełny adres URL? Czy powinienem wtedy zastosować regułę 2 lub zasadę 3 z góry LUB Być może ZARÓWNO jak encodeURIComponent (encodeURI (theCompleteURI))
Panu Logic

10

encodeURIComponent (): zakłada, że ​​jego argumentem jest część (na przykład protokół, nazwa hosta, ścieżka lub ciąg zapytania) identyfikatora URI. Dlatego ucieka od znaków interpunkcyjnych używanych do oddzielania części identyfikatora URI.

encodeURI (): służy do kodowania istniejącego adresu URL


7

Różnica między encodeURIi encodeURIComponent:

encodeURIComponent(value)służy głównie do kodowania wartości parametrów queryString i koduje każdy odpowiedni znak w value. encodeURIignoruje przedrostek protokołu ( http://) i nazwę domeny.


W bardzo, bardzo rzadkich przypadkach, gdy chcesz zaimplementować ręczne kodowanie w celu zakodowania dodatkowych znaków (chociaż nie muszą być one kodowane w typowych przypadkach), takich jak ! *:, możesz użyć:

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

( źródło )


6
Nie powinieneś uciec tym postaciom w url.
Arashsoft,

Jak mówi cytowana dokumentacja: „te znaki nie mają sformalizowanych zastosowań ograniczania URI”
caesarsol

@ caesarsol, więc powinienem edytować swoją odpowiedź. daj mi znać, co
myślisz,

po prostu bezużyteczne jest kodowanie tych znaków, chyba że robisz coś z normalnych przypadków użycia kodowania adresów URL :)
caesarsol,

2

Inne odpowiedzi opisują cele. Oto znaki, które każda funkcja faktycznie skonwertuje :

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

Wszystkie powyższe znaki są konwertowane na kody szesnastkowe procentowe. Spacja do %20, procent do %25itp. Znaki poniżej przechodzą przez niezmienione.

Oto znaki, których funkcje NIE konwertują :

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )

-4

Jako ogólną zasadę należy stosować encodeURIComponent. Nie bój się długiej nazwy, myśląc, że jest bardziej specyficzna w użyciu, dla mnie jest to najczęściej stosowana metoda. Nie daj się też wciągnąć w używanie encodeURI, ponieważ przetestowałeś go i wydaje się, że koduje poprawnie, prawdopodobnie nie jest to to, co chciałeś użyć, i mimo że Twój prosty test z użyciem „Fred” w polu imienia zadziałał, znajdziesz później, gdy użyjesz bardziej zaawansowanego tekstu, takiego jak dodanie znaku handlowego lub hashtagu, nie powiedzie się. Możesz spojrzeć na inne odpowiedzi z powodów, dla których tak jest.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.