2012-02-12 14 views
8

Czy jest jakieś prawidłowe użycie funkcji encodeURI javascript?powinno być kiedykolwiek używane encodeURI?

O ile mogę powiedzieć, kiedy staramy się żądanie HTTP ty powinien albo:

  • kompletnym URI
  • jakiś fragment chcesz umieścić w URI, który jest albo ciąg znaków Unicode lub kod bajtowy UTF-8

W pierwszym przypadku oczywiście nic nie trzeba robić, aby o to poprosić. Uwaga: jeśli rzeczywiście chcesz przekazać go jako parametr (np. Url = http ...), to masz instancję drugiego przypadku, który wygląda jak URI.

W drugim przypadku, należy zawsze przekonwertować ciąg Unicode na UTF-8, a następnie zadzwonić encodeURIComponent uciec wszystkie znaków przed dodaniem go do identyfikatora URI. (Jeśli masz sekwencję bajtów UTF-8 zamiast ciągu unicode, możesz pominąć krok convert-to-utf8).

Zakładając, że niczego nie przeoczyłem, nie widzę prawidłowego użycia dla encodeURI. Jeśli go używasz, prawdopodobnie skonstruowałeś nieprawidłowy identyfikator URI, a następnie próbujesz go "odkażić" po fakcie, który jest po prostu niemożliwy, ponieważ nie wiesz, które postacie były przeznaczone dosłownie, i które miały zostać usunięte .

Widziałem wiele porad dotyczących używania escape(), ale nie widzę nikogo zniechęcającego encodeURI. Czy brakuje ważnego zastosowania?

+2

"Niektóre fragmenty, które chcesz umieścić w URI", jak sądzę, można nazwać "składnikiem URI". "W drugim przypadku zawsze powinieneś przekonwertować ciąg znaków Unicode na UTF-8" - nie w JavaScript. 'encodeURIComponent' automatycznie przekształci ciąg znaków w kodowanie UTF-8 (a' decodeURIComponent' skonwertuje oktety UTF-8 z powrotem na znaki Unicode). – mgiuca

Odpowiedz

10

Mam blog post, który odpowiada na to pytanie bardzo szczegółowo.

Powinieneś nigdy użycie encodeURI skonstruować URI programowo, z powodów mówisz - należy zawsze używać encodeURIComponent na poszczególne składniki, a następnie skomponować je w kompletny URI.

Gdzie encodeURI jest prawie przydatna jest w „czyszczenie” URI, zgodnie z Postel's Law („Bądź liberalnym w tym, co akceptują i konserwatywny w tym, co wysłać.”) Jeśli ktoś daje pełne URI go, może zawierać niedozwolone znaki, takie jak spacje, niektóre znaki ASCII (takie jak podwójne cudzysłowy) i znaki Unicode. encodeURI może zostać użyty do przekonwertowania tych niedozwolonych znaków do legalnych sekwencji z sekwencjami ucieczkowymi, bez ograniczników kodowania. Podobnie, można użyć decodeURI do "ładnego drukowania" identyfikatora URI, pokazując sekwencje zbiegające się w procentach jako technicznie nielegalne nagie postacie.

Na przykład, URL:

http://example.com/admin/login?name=Helen Ødegård&gender=f 

jest nielegalne, ale wciąż jest całkowicie jednoznaczne.encodeURI konwertuje go do ważnego identyfikatora URI:

http://example.com/admin/login?name=Helen%20%C3%98deg%C3%A5rd&gender=f 

Przykładem aplikacji, która może chcesz zrobić tego rodzaju „czyszczenia” URI jest przeglądarka internetowa. Po wpisaniu adresu URL na pasku adresu, należy spróbować przekonwertować wszystkie niedozwolone znaki na wartości procentowe, zamiast tylko popełnić błąd. Oprogramowanie przetwarzające identyfikatory URI (np. Skrobak HTML, który chce uzyskać wszystkie adresy URL w hiperlinkach na stronie) może również chcieć zastosować tego rodzaju czyszczenie w przypadku, gdy którykolwiek z adresów URL jest technicznie nielegalny.

Niestety, encodeURI ma krytyczną wadę polegającą na tym, że wymyka się znakom "%", czyniąc go całkowicie bezużytecznym dla czyszczenia URI (podwójnie ucieknie od dowolnego identyfikatora URI, który już uciekł z procenta). Dlatego ja pożyczyłem Mozilla's fixedEncodeURI funkcję i poprawił go tak, aby prawidłowo czyści URI:

function fixedEncodeURI(str) { 
    return encodeURI(str).replace(/%25/g, '%').replace(/%5B/g, '[').replace(/%5D/g, ']'); 
} 

Dlatego należy zawsze używać encodeURIComponent skonstruować URI wewnętrznie. Nigdy nie używaj tylko encodeURI, ale możesz użyć mojego fixedEncodeURI, aby spróbować "wyczyścić" identyfikatory URI, które zostały dostarczone z zewnętrznego źródła (zwykle jako część interfejsu użytkownika).

+1

Widzę (i zgadzam się) z użyciem tutaj, ale nie jestem przekonany, że encodeURI jest implementacją tego, co opisujesz. encodeURI konwertuje "% 2F" na "% 252F", co zmienia znaczenie identyfikatora URI poprzez podwójne ucieczkę niektórych z nich. – gfxmonk

+0

Argh, masz rację. Zaktualizowałem swój wpis na blogu (wyszukaj "Edytuj"). Zawiera on funkcję o nazwie fixedEncodeURI (pożyczoną od Mozilli i ulepszoną), która zachowuje się tak, jak opisałem pierwotnie. Rzeczywista funkcja encodeURI w obecnym stanie to kompletne śmieci. – mgiuca

+0

Edytowałem odpowiedź, aby pokazać lukę w encodeURI, z sugerowanym obejściem. – mgiuca

5

encodeURI nie koduje następujących elementów:, /? : @ & = + $ #, podczas gdy encodeURIComponent to robi.

Istnieje wiele powodów, dla których warto użyć encodeURI przez encodeURIComponent, na przykład przypisanie adresu URL jako wartości zmiennej. Chcesz zachować adres URL, ale kodować ścieżki, łańcuch zapytania i wartości mieszania. Użycie encodeURIComponent spowodowałoby niepoprawność adresu URL.

+1

co masz na myśli, mówiąc o "przypisaniu adresu URL jako wartości zmiennej"? Czy chodzi o uwzględnienie adresu URL jako wartości w parametrze zapytania? Jeśli masz adres URL, taki jak "http://example.com/?x=1&y=2" i chcesz go przekazać jako parametr zapytania, zdecydowanie powinieneś użyć encodeURIComponent, ponieważ encodeURI nie ujdzie "+". – gfxmonk

+0

var x = myencodedurl; –

+0

Przykro mi, ale to nie ma sensu. Dlaczego miałbyś kiedykolwiek zmienić wartość _ ciągu znaków (czyli jaki URI będzie w JS), aby zapisać go w zmiennej? – gfxmonk

Powiązane problemy