Чи слід використовувати encodeURI або encodeURIComponent для кодування URL-адрес?


281

Який із цих двох методів слід використовувати для кодування URL-адрес?



13
Одна з головних відмінностей полягає в тому encodeURI, що не буде кодувати /так: encodeURIComponent("ac/dc")=> ac%2Fdcі encodeURI("ac/dc")=>ac/dc

Це може бути корисним: "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." Джерело
user1063287

Також дивіться конкретний розділ під назвою encodeURIComponent differs from encodeURI as follows: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1063287

Відповіді:


324

Це залежить від того, що ти насправді хочеш зробити.

encodeURI передбачає, що вхід - це повний URI, який може мати деякі символи, які потребують кодування в ньому.

encodeURIComponent буде кодувати все з особливим значенням, тому ви використовуєте його для компонентів URI, таких як

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

108

Якщо ви кодуєте рядок для введення компонента URL (параметр запиту), вам слід зателефонувати encodeURIComponent.

Якщо ви кодуєте наявну URL-адресу, зателефонуйте encodeURI.


1
Якщо я використовую ajax, як я розшифрую URL, який передається до php?
Адітя Шукла

6
Ви цього не робите. Веб-сервер робить це автоматично.
Квентін

@Aditya: Це залежить від того, що ти робиш.
СЛАкс

@slaks. Я передаю параметри через get, тому я хочу отримати їх у php.
Адітя Шукла

2
Ну. Я, можливо, говорив трохи поспішно, коли я сказав, що веб-сервер це зробить, але незалежно від того, яку бібліотеку ви використовуєте для читання даних форм, подбайте про неї.
Квентін

46

xkr.us має велику дискусію, з прикладами. Щоб процитувати їх резюме:

Метод escape () не кодує символ +, який інтерпретується як пробіл на стороні сервера, а також генерується формами з пробілами в їх полях. У зв'язку з цим недоліком і тим, що ця функція не справляється з символами, що не належать до ASCII, слід уникати використання escape (), коли це можливо. Найкращою альтернативою зазвичай є encodeURIComponent ().

escape () не кодує: @ * / +

Використання методу encodeURI () трохи більш спеціалізовано, ніж escape (), оскільки він кодує URI, на відміну від рядка запитів, який є частиною URL-адреси. Використовуйте цей метод, коли вам потрібно кодувати рядок, який буде використовуватися для будь-якого ресурсу, що використовує URI і потрібні певні символи, щоб вони не були закодовані. Зауважте, що цей метод не кодує символ ', оскільки він є дійсним символом в URI.

encodeURI () не буде кодувати: ~! @ # $ & * () =: /,;? + '

Нарешті, метод encodeURIComponent () повинен застосовуватися в більшості випадків при кодуванні одного компонента URI. Цей метод буде кодувати певні символи, які зазвичай розпізнаються як спеціальні символи для URI, так що багато компонентів можуть бути включені. Зауважте, що цей метод не кодує символ ', оскільки він є дійсним символом в URI.

encodeURIComponent () не кодує: ~! * () '


Нещодавно дізнався. Сервери TOMCAT 9 детальніше стосуються того, що ви можете надіслати на URL. encodeURIComponent (), здається, працює краще в тих випадках, коли у вас є "пробіли" в тому, що потрібно кодувати. Tomcat 8 не піклувався, але 9 - більш конкретний.
Aggie Jon від 87

Отже, іншими словами encodeURIНЕ працює, якщо ви намагаєтеся перетворити ім'я файлу в URL і ім'я файлу має #в ньому
Gman

17

Ось підсумок.

  1. escape () не кодує @ * _ + -. /

    Не використовуйте.

  2. encodeURI () не буде кодувати AZ az 0-9; , /? : @ & = + $ - _. ! ~ * '() #

    Використовуйте його, коли ваш вхід - це повна URL-адреса, наприклад " https://searchexample.com/search?q=wiki "

  3. encodeURIComponent () не буде кодувати AZ az 0-9 - _. ! ~ * '() Використовуйте його, коли ваш вхід є частиною повної URL-адреси, наприклад const queryStr = encodeURIComponent(someString)

1
Це відмінна відповідь, оскільки вона точно говорить, що вони роблять. Однак у мене все ще виникає питання, що мені слід використовувати і коли. Що робити, якщо мій компонент URI - це повна URL-адреса? Якщо я повинен використовувати правило 2 або правило 3 зверху АБО, можливо, БУТИ, як encodeURIComponent (encodeURI (theCompleteURI))
Panu Logic

10

encodeURIComponent (): передбачає, що його аргумент є частиною (наприклад, протокол, ім'я хоста, шлях або рядок запиту) URI. Тому він уникає розділових знаків, які використовуються для розділення частини URI.

encodeURI (): використовується для кодування існуючого URL-адреси


7

Різниця між encodeURIта encodeURIComponent:

encodeURIComponent(value)в основному використовується для кодування значень параметрів queryString, і він кодує всі застосовні символи в value. encodeURIігнорує префікс протоколу ( http://) та доменне ім'я.


У дуже, дуже рідкісних випадках, коли ви хочете застосувати ручне кодування для кодування додаткових символів (хоча вони не потребують кодування в типових випадках), таких як:, ! *тоді ви можете використовувати:

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

( джерело )


6
Вам не слід уникати цих характерів в URL-адресі.
Arashsoft

Як зазначено в цитованій документації: "Ці символи не мають формалізованого використання обмеження URI"
цезарсол

@caesarsol так, чи слід редагувати свою відповідь. дайте мені знати ваші думки, тому що я не можу зрозуміти, що означає цитована документація ..
Т.Тодуа

просто марно кодувати ці символи, якщо ви не робите щось із звичайних випадків використання кодування URL-адрес :)
caesarsol

2

Інші відповіді описують цілі. Ось символи, які кожна функція фактично перетворить :

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 + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

Усі символи, перераховані вище, перетворюються на відсотковий шістнадцятковий код. Пробіл до %20, відсотки до %25тощо. Символи нижче проходять без змін.

Ось символи, які НЕ перетворюватимуть :

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

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

-4

Як загальне правило використання encodeURIComponent. Не лякайтеся довгого імені, думаючи, що це більш специфічне в його використанні, для мене це більш часто використовуваний метод. Крім того, вам не вдасться використовувати encodeURI, тому що ви протестували його, і воно, здається, кодує належним чином, це, мабуть, не те, що ви мали намір використовувати, і хоча ваш простий тест із використанням "Fred" у полі імені спрацював, ви знайдете пізніше, коли ви використовуєте більш вдосконалений текст, як-от додавання амперсанда або хештегу, це не вдасться Ви можете подивитися на інші відповіді з причин, чому це так.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.