Безпечні символи для дружнього URL [закрито]


168

Мені потрібно створити веб-сайт, на якому будуть статті, і я хотів би зробити для нього дружні URL-адреси, наприклад URL-адресу сторінки з

Назва: Стаття Тест

повинні стати: http://www.example.com/articles/article_test.

Звичайно, мені потрібно видалити деякі символи з назви, як-от ?або #, але я не впевнений, які з них видалити.

Хтось може сказати мені, які персонажі безпечно зберігати?


Був аналогічне питання, тут . Перевірте це, можливо, ви знайдете і кілька корисних відповідей (їх було досить багато).
Грак

Відповіді:


210

Цитувати розділ 2.3 RFC 3986 :

"Символи, дозволені в URI, але не мають зарезервованої мети, називаються незарезервованими. До них відносяться великі та малі літери, десяткові цифри, дефіс, крапка, підкреслення та тильда."

ALPHA  DIGIT  "-" / "." / "_" / "~"

Зауважимо, що RFC 3986 містить менше зарезервованих розділових знаків, ніж старіші RFC 2396 .


@Skip Head, чи "символи" включають символи, кодовані латиною, як çі õ?
Mohamad

6
@Mohamad: Ні, лише ASCII, хоча підтримка UTF-8 стає кращою.
Дітріх Епп

@Dietrich Epp, дякую. Я думаю, це не має значення, чи URL-адреса призначена для оздоблення та SEO, наприклад: www.mysite.com/
evidencepostIdSense/

1
@Mohamad: Остання частина там буде змінена під кришкою на post-title-with-%C3%A7-and-%C3%B5, але вона все одно відображатиметься в рядку місцезнаходження користувача як post-title-with-ç-and-õ.
Дітріх Епп

7
Ваші читачі португальські, тому використовуйте португальські символи.
Дітріх Епп

107

Існує два набори символів, на які потрібно стежити: зарезервований і небезпечний .

В зарезервовані символи:

  • ampersand ("&")
  • долар ("$")
  • знак плюс ("+")
  • кома (",")
  • передня косою рисою ("/")
  • двокрапка (":")
  • напів-двокрапка (";")
  • дорівнює ("=")
  • знак питання ("?")
  • Символ "At" ("@")
  • фунт ("#").

Символи, які зазвичай вважаються небезпечними :

  • пробіл ("")
  • менше та більше ніж ("<>")
  • відкрити та закрити дужки ("[]")
  • відкрити та закрити дужки ("{}")
  • труба ("|")
  • зворотний нахил ("\")
  • caret ("^")
  • відсотків ("%")

Можливо, я забув одне чи декілька, що призводить до того, що мені лунає відповідь Карла V. Зрештою, вам, ймовірно, краще скористатися "білим списком" дозволених символів, а потім кодувати рядок, а не намагатися бути в курсі символів, заборонених серверами та системами.


#- це зарезервований символ, який використовується для закладок на певній сторінці, створений наявністю одного HTML-елемента з відповідним атрибутом name або id-атрибутом (sans #-symbol).
TheLonelyGhost

Дякую - я оновив відповідь.
Gary.Ray

Знак запитання відображається як зарезервований, так і небезпечний - я вважаю це лише зарезервованим, але я можу помилитися
Джонатан Базіле,

6
Здається, інші не згодні з тим, що тильда ~небезпечна. Ви впевнені, що це?
DRS

3
Білий список не дуже хороший, якщо обробляти інші мови, крім англійської. У Unicode просто занадто багато OK-кодів. Тому чорний список небезпечних, ймовірно, буде найпростішим для здійснення у регулярних виразах.
Патанджалі

41

Найкраще зберігати лише деякі символи (білий список), а не видаляти певні символи (чорний список).

Ви можете технічно дозволити будь-який символ, до тих пір, поки ви його правильно закодувати. Але, щоб відповісти в дусі питання, ви повинні дозволити лише цим персонажам:

  1. Малі літери (перетворіть великі регістри в малі)
  2. Числа, від 0 до 9
  3. Тире - або підкреслення _
  4. Тільда ​​~

Все інше має потенційно особливе значення. Наприклад, ви можете подумати, що ви можете використовувати +, але його можна замінити пробілом. & теж небезпечно, особливо, якщо використовувати деякі правила перезапису.

Як і інші коментарі, ознайомтеся зі стандартами та технічними характеристиками, щоб отримати повну інформацію.


15
Сьогодні я виявив, що попередній час - це поганий вибір символів, який потрібно використовувати для безпечного для URL-кодеру Base64, оскільки трапляються рідкісні випадки, коли ваші кодовані дані можуть видавати дві послідовні крапки (".."), що є важливим для що він посилається на батьківський каталог.
похл

5
@pohl: це лише проблема, якщо ваша URL-адреса використовується як шлях до файлу, або у вашому коді, або якщо ваш веб-сервер намагається відобразити URL-адресу у файлах, перш ніж переслати запит у сценарій (на жаль, дуже поширений).
Андре Карон

4
Насправді, у нашому випадку використовувати його як шлях до файлу було б нормально, оскільки в файлах unix дозволено мати кілька і навіть послідовних крапок у своїх назвах. Для нас проблема виникла в інструменті моніторингу під назвою Site Scope, який має помилку (можливо, наївний вираз), і він повідомляв про помилкові помилкові простої. Для нас ми застрягли на старій версії Сфера сайту, команда адміністратора відмовляється платити за оновлення, і один дуже важливий клієнт має Сфера сайту (не еквівалент), записаний у їхньому контракті. Правда, більшість не опиняться в моєму взутті.
похл

8
Слава богу, що хтось опублікував список, не сильно розбещуючись. Щодо крапки (.) - як сказав @pohl, не використовуйте її! Ось ще один дивний випадок на IIS (не знаю, чи трапляється це на інших веб-серверах): якщо він знаходиться в кінці вашої URL-адреси, ви, швидше за все, отримаєте помилку 404 (він спробує шукати [/ pagename] сторінка)
nikib3ro

34

Завжди безпечний

Вони безпечні (теоретично / спец.), В основному в будь-якому місці, крім доменного імені.
Процент-кодуйте що-небудь, що не перераховане, і вам добре піти.

    A-Z a-z 0-9 - . _ ~ ( ) ' ! * : @ , ;

Іноді безпечно

Безпечний лише при використанні в конкретних компонентах URL-адреси; використовувати обережно.

    Paths:     + & =
    Queries:   ? /
    Fragments: ? / # + & =
    

Ніколи не безпечно

Відповідно до специфікації URI (RFC 3986), всі інші символи повинні бути закодовані у відсотках. Це включає:

    <space> <control-characters> <extended-ascii> <unicode>
    % < > [ ] { } | \ ^
    

Якщо максимальна сумісність викликає занепокоєння, обмежте діаграму на AZ az 0-9 - _.
(з періодами лише для розширень імен файлів).

Зберігайте контекст у розумі

Навіть якщо дійсна за специфікацією, URL-адреса все ще може бути "небезпечною", залежно від контексту. Наприклад, як файл: /// URL, що містить недійсні символи файлу, або компонент запиту, що містить "?", "=" Та "&", коли не використовується як роздільник. Правильне поводження з цими справами, як правило, залежить від ваших сценаріїв, і їх можна вирішити, але це потрібно пам’ятати.


Чи можете ви надати якісь джерела для другої претензії ("Іноді безпечно")? Зокрема, я вважаю, що ви неправильно сказали, що =це не безпечно для запитів. Наприклад, FIQL приймає знаки рівності та описує себе як "зручний для URI" та "оптимізований і призначений для використання в компоненті запиту". У моєму трактуванні RFC 3986 явно дозволяє запити "=", "&", "+" та інші.
DanielM

@DanielM "?", "=" Та "&" дійсні в запитах на специфікацію, хоча на практиці вони широко використовуються для розбору пар імен-значень у запиті. Тому вони можуть бути небезпечними як частина самих імен / значень. Незалежно від того, чи це є "небезпечним", може бути питанням думки.
Beejor

Деякі джерела, за запитом. (1) RFC 3986, розділ 3.4: "[...] компоненти запиту часто використовуються для перенесення ідентифікаційної інформації у вигляді пар" ключ = значення "[...]" (2) URL-адреса WhatWG Spec, сек. 6.2: "Конструювання та упорядкування об’єкта URLSearchParams є досить простим: [...] params.toString() // "key=730d67"" (3) Посібник з PHP, http-build-query: "Створення рядка запиту, кодованого URL-адресою. [...] Вищенаведений приклад виведе: 0=foo&1=bar[...]"(4) J. Starr, Perishable Press:" Під час створення веб-сторінок часто потрібно додавати посилання, які потребують параметризованих рядків запитів. "
Бейор

@Beejor: Я будую URL-адресу та використовую '-' і ';' під час будівництва. Це не веб-додаток, а мобільний додаток. Чи не веб-розробник, а значить, я б був у безпеці, якщо використовую вищевказані символи у власності Path? docs.microsoft.com/en-us/dotnet/api/…
karsnen

1
@karsnen Це дійсні символи URL-адреси. Хоча якщо вони використовуються для посилання на контури локальної файлової системи, майте на увазі, що деякі системи забороняють певні символи у назви файлів. Наприклад, "file: /// path / to / my: file.ext" буде недійсним на Mac.
Бейор

17

Дивлячись на RFC3986 - Уніфікований ідентифікатор ресурсу (URI): Загальний синтаксис , ваше запитання обертається навколо компонента шляху URI.

    foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \ /                        \
     urn:example:animal:ferret:nose

Посилаючись на розділ 3.3, дійсні символи для URI segmentмають тип pchar:

pchar = незарезервований / pct-закодований / sub-delims / ":" / "@"

Який розбивається на:

ALPHA / DIGIT / "-" / "." / "_" / "~"

pct-encoded

"!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

":" / "@"

Або іншими словами: Ви можете використовувати будь-яку (НЕ управления-) символ з таблиці ASCII , за винятком / , ?, #, [і ].

Це розуміння підтримується RFC1738 - Уніфікованими локаторами ресурсів (URL) .


2
Це чудовий приклад теоретично правильної відповіді, що призводить до неприємностей при застосуванні до реального світу, в якому ми насправді живемо. Це правда, що більшість із цих персонажів не спричинить проблеми більшу частину часу. Але в реальному світі існують такі речі, як проксі, маршрутизатори, шлюзи, реле тощо, які "люблять" перевіряти та взаємодіяти з URL-адресами способами, що нехтують теоретичним стандартом. Щоб уникнути цих підводних каменів, ви майже обмежуєтесь уникати всього, крім буквено-цифрових знаків, тире, підкреслення та періоду.
deltamind106

1
@ deltamind106 Чи можете ви навести приклади та / або посилання, щоб уточнити, які з цих символів є безпечними згідно з RFC, насправді ні? Я вважаю за краще дотримуватися фактів, підкріплених стандартами у своїй відповіді, і я радий оновити свою відповідь, якщо ви зможете точно визначити будь-які факти, якими я, можливо, нехтував.
Філцен

2
@ deltamind106 Я б запропонував спробувати змусити товари дотримуватися стандартів, а не казати розробникам не робити цього. Я вважаю ваше попередження заслуженим, але ми повинні зробити свою роль у повідомленні постачальників про невідповідність, якщо це необхідно.
Ло-Тан

@Philzen: я будую URL-адресу та використовую '-' і ';' під час будівництва. Це не веб-додаток, а мобільний додаток. Чи не веб-розробник, а значить, я б був у безпеці, якщо використовую вищевказані символи у власності Path? docs.microsoft.com/en-us/dotnet/api/…
karsnen

1
@karsnen Так, звичайно, -і ;це безпечно, саме так явно стверджується моя відповідь та RFC.
Фільцен

12

незарезервовано = ALPHA / DIGIT / "-" / ". / "_" / "~"


3
Чи не означає "АЛЬФА" "DIGIT"? Я припускаю, що ALPHA є коротким для "буквено-цифрових", а буквено-цифрові означають великі, малі та цифри
Люк

11
Насправді альфа не означає буквено-цифрові. Альфа та цифра - це дві різні речі, а буквено-цифрові - це поєднання цих речей. Він міг би так написати свою відповідь: АЛЬФАНУМЕРИЧНИЙ / "-" / ". / "_" / "~"
MacroMan

1
Позначення ABNF для "незарезервованих" в RFC 3986 перераховує їх окремо.
Патанджалі

11

З контексту, який ви описуєте, я підозрюю, що те, що ви насправді намагаєтеся зробити, - це щось, що називається "SEO-слизом". Найкраща загальновідома практика для них:

  1. Перетворити на малі регістри
  2. Перетворити цілі послідовності символів, крім az та 0-9, в один дефіс (-) (не підкреслюючи)
  3. Видаліть із URL-адреси "стоп-слова", тобто слова, які не мають значення, які можна вказувати на зразок "a", "an" та "the"; Google "зупинити слова" для широких списків

Так, як приклад, стаття під назвою "Використання! @% $ * Для представлення присяги в коміксах" отримає кулі "використання-представляй-присягай-комікси".


Це дійсно вдалий підхід для видалення цих "зупиняючих слів" з URL? Чи могли б пошукові системи штрафувати веб-сайт через це?
Пауло

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

1
@chaos Ви все-таки рекомендуєте знімати StopWord, якщо врахувати це: seobythesea.com/2008/08/google-stopword-patent Також можете порекомендувати хороший список зупинок? Це найкращий список, який я знайшов поки що - link-assistant.com/seo-stop-words.html
nikib3ro

@ kape123 Це не дуже добре для мене перелік. "c" і "d" - це мови програмування, і багато інших цих слів також виглядають важливими. Я, мабуть, просто знімаю основні: a, і, is, on, of, or, the, with.
квітня 1616


6

З точки зору SEO, дефіси віддають перевагу над підкресленнями. Перетворити на малі, видалити всі апострофи, а потім замінити всі не алфавітно-цифрові рядки символів одним дефісом. Обріжте зайві дефіси від початку та кінця.


3

У мене була подібна проблема, я хотів мати гарні URL-адреси і дійшов висновку, що я повинен дозволяти лише літери, цифри - і _ в URL-адресах. Це добре, тоді я написав хороший регулярний вираз і зрозумів, що він розпізнає, що всі символи UTF8 не букви в .NET, і він був накручений. Це, мабуть, є проблемою відомості для .NET regex engine. Так я дійшов до цього рішення:

private static string GetTitleForUrlDisplay(string title)
{
    if (!string.IsNullOrEmpty(title))
    {
        return Regex.Replace(Regex.Replace(title, @"[^A-Za-z0-9_-]", new MatchEvaluator(CharacterTester)).Replace(' ', '-').TrimStart('-').TrimEnd('-'), "[-]+", "-").ToLower();
    }
    return string.Empty;
}


/// <summary>
/// All characters that do not match the patter, will get to this method, i.e. useful for unicode chars, because
/// .NET impl of regext do not handle unicode chars. So we use char.IsLetterOrDigit() which works nicely and we 
/// return what we approve and return - for everything else.
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private static string CharacterTester(Match m)
{
    string x = m.ToString();
    if (x.Length > 0 && char.IsLetterOrDigit(x[0]))
    {
        return x.ToLower();
    }
    else
    {
        return "-";
    }
}

3
Фактично .NET реджекси фактично підтримують unicode. Ви повинні використовувати класи символів Unicode, наприклад \ p {L} для всіх літер. Дивіться msdn.microsoft.com/en-us/library/20bw873z.aspx#CategoryOrBlock
TheCycoONE

1

Мені було дуже корисно кодувати мій URL у безпечному, коли я повертав значення через ajax / php до URL, який потім читався сторінкою ще раз.

Вихід PHP з кодером URL для спеціального символу &

//PHP returning the sucess info of ajax request
echo "".str_replace('&','%26',$_POST['name'])." category was changed";

//javascript sending the value to url
window.location.href='time.php?return=updated&val='+msg;

//javascript/php executing the function printing the value of the url,
//now with the text normally lost in space because of the reserved & character.

setTimeout("infoApp('updated','<?php echo $_GET['val'];?>');",360);

Сподіваюся, хтось вважає мої маленькі витяги з коду корисними! :)


0

Я думаю, ви шукаєте щось на кшталт "Кодування URL-адрес" - кодування URL-адреси, щоб було безпечно використовувати в Інтернеті:

Ось посилання на це. Якщо ви не хочете будь-яких спеціальних символів, просто видаліть будь-які, які потребують кодування URL-адрес:

http://www.w3schools.com/TAGS/ref_urlencode.asp


-4

Між 3-50 символами. Може містити малі літери, цифри та спеціальні символи - крапку (.), Тире (-), підкреслення (_) та зі швидкістю (@).


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