Какие символы безопасны для создания URL-адресов?

Я создаю веб-сайт со статьями, и мне нужно, чтобы у статей были удобные URL-адреса на основе заголовка.

Например, если заголовок моей статьи "Article Test", я хотел бы, чтобы URL-адрес был http://www.example.com/articles/article_test.

Однако заголовки статей (как и любая строка) могут содержать несколько специальных символов, которые невозможно поместить буквально в мой URL-адрес. Например, я знаю, что нужно заменить ? или #, но не знаю всех остальных.

Какие символы разрешены в URL-адресах? Что безопасно хранить?


person Paulo    schedule 29.03.2009    source источник
comment
Аналогичный вопрос был здесь. Зацените, там тоже можно найти полезные ответы (их было довольно много).   -  person Rook    schedule 30.03.2009
comment
Я переформулировал вопрос, чтобы он был более ясным. Вопросы и ответы полезны и хорошего качества. (48 человек, в том числе и я, добавили в избранное) На мой взгляд, его нужно открыть заново.   -  person Jonathan Allard    schedule 18.11.2020


Ответы (13)


Чтобы процитировать раздел 2.3 RFC 3986:

Символы, которые разрешены в URI, но не имеют зарезервированного назначения, называются незарезервированными. К ним относятся прописные и строчные буквы, десятичные цифры, дефис, точка, подчеркивание и тильда.

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

Обратите внимание, что RFC 3986 содержит меньше зарезервированных знаков препинания, чем более старый RFC 2396.

person Skip Head    schedule 29.03.2009
comment
@Skip Head, включают ли символы символы в латинской кодировке, такие как ç и õ? - person Mohamad; 10.06.2011
comment
@Mohamad: Нет, только ASCII, хотя поддержка UTF-8 улучшается. - person Dietrich Epp; 19.06.2011
comment
@ Дитрих Эпп, спасибо. Думаю, не имеет значения, предназначен ли URL-адрес для украшения и SEO, например: www.mysite.com/[postIdpting/post-title-with-ç-and-õ - person Mohamad; 19.06.2011
comment
@Mohamad: Последняя часть будет изменена под капотом на post-title-with-%C3%A7-and-%C3%B5, но она по-прежнему будет отображаться в строке местоположения пользователя как post-title-with-ç-and-õ. - person Dietrich Epp; 19.06.2011
comment
@ Дитрих Эпп, это действительно интересно. Не имел представления. Влияет ли это на SEO? Вы бы порекомендовали заменить такие символы их ближайшими английскими эквивалентами? Все мои читатели - португальцы, использующие такие символы! - person Mohamad; 19.06.2011
comment
Ваши читатели португальцы, поэтому используйте португальские символы. - person Dietrich Epp; 19.06.2011
comment
Поскольку упомянутый документ очень старый, и этот пост тоже. Просто хотел знать, действительно ли это или у нас есть обновленный документ. - person prasingh; 31.05.2019
comment
А как насчет запятых? , - person Protector one; 18.01.2021

Обратите внимание на два набора символов: зарезервировано и небезопасно.

Зарезервированные символы:

  • амперсанд (&)
  • доллар ($)
  • знак плюс (+)
  • запятая (,)
  • косая черта (/)
  • двоеточие (:)
  • точка с запятой (;)
  • равно (=)
  • вопросительный знак (?)
  • Символ 'At' (@)
  • фунт (#).

Небезопасными обычно считаются следующие символы:

  • Космос ( )
  • меньше и больше (‹›)
  • открывающие и закрывающие скобки ([])
  • открывающие и закрывающие фигурные скобки ({})
  • труба (|)
  • обратная косая черта ()
  • каретка (^)
  • процентов (%)

Возможно, я забыл один или несколько, из-за чего я повторяю Ответ Карла V. В конечном итоге вам, вероятно, будет лучше использовать белый список разрешенных символов и затем кодировать строку, чем пытаться быть в курсе символов, которые запрещены серверами и системами.

person Gary.Ray    schedule 29.03.2009
comment
# - зарезервированный символ, используемый для закладок на определенной странице, созданный с помощью одного элемента HTML с совпадающим атрибутом имени или атрибутом id (без символа #). - person TheLonelyGhost; 12.08.2014
comment
Знак вопроса отображается здесь как зарезервированный и как небезопасный - я думаю, что он только зарезервирован, но могу ошибаться - person Jonathan Basile; 26.05.2015
comment
Другие, кажется, не согласны с тем, что тильда ~ небезопасна. Вы в этом уверены? - person drs; 15.06.2015
comment
Белый список не очень хорош при работе с языками, отличными от английского. В Unicode слишком много кодов ОК. Поэтому занесение небезопасных в черный список, вероятно, будет проще всего реализовать в регулярных выражениях. - person Patanjali; 26.11.2015
comment
тильда ~ кажется безопасной: символы, которые разрешены в URI, но не имеют зарезервированного назначения, называются незарезервированными. К ним относятся прописные и строчные буквы, десятичные цифры, дефис, точка, подчеркивание и тильда. unreserved = АЛЬФА / ЦИФРА / - /. / _ / ~, из ietf.org/rfc/rfc3986.txt - person jorgefpastor; 18.06.2016
comment
Я сделал рабочее регулярное выражение на основе этого ответа здесь: regex101.com/r/9VBu66/1 со следующими примечаниями. 1. Первая часть помещает в черный список символы, отличные от ascii, поэтому вам нужно удалить это, если вы хотите поддерживать Unicode и 2. Я не заносит в черный список /, потому что я разрешаю подкаталоги. Я использую регулярное выражение: /([^\x00-\x7F]|[&$\+,:;=\?@#\s<>\[\]\{\}|\\\^%])+/ - person andyvanee; 02.12.2020
comment
% процент всегда небезопасен, так как он используется точно для кодирования небезопасных символов. - person Guillermo Prandi; 11.12.2020
comment
Думаю, есть три комплекта. Третий - символы, отличные от ASCII. - person Peter Mortensen; 14.01.2021
comment
Вы можете обновить свой ответ? - person Peter Mortensen; 26.01.2021

Всегда в безопасности

Теоретически и согласно спецификации они безопасны практически везде, кроме доменного имени. Процентное кодирование всего, чего нет в списке, и готово.

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

Иногда безопасно

Безопасно только при использовании в определенных компонентах URL; используйте с осторожностью.

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

Никогда не безопасно

Согласно спецификации URI (RFC 3986), все остальные символы должны быть закодированы в процентах. Это включает:

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

Если максимальная совместимость вызывает беспокойство, ограничьте набор символов A-Z a-z 0-9 - _. (с точками только для расширений файлов).

Помните о контексте

Даже если он действителен в соответствии со спецификацией, URL-адрес может быть небезопасным в зависимости от контекста. Например, URL-адрес file: ///, содержащий недопустимые символы имени файла, или компонент запроса, содержащий?, = И &, если он не используется в качестве разделителей. Правильная обработка этих случаев, как правило, зависит от ваших сценариев, и ее можно обойти, но об этом следует помнить.

person Beejor    schedule 04.11.2016
comment
Не могли бы вы предоставить какие-либо источники для вашего второго заявления (иногда безопасного)? В частности, я считаю, что вы ошибаетесь, говоря, что = небезопасно для запросов. Например, FIQL принимает знаки равенства и описывает себя как Удобен для URI, оптимизирован и предназначен для использования в компоненте запроса. В моей интерпретации RFC 3986 явно разрешает =, &, + и другие в запросах. - person DanielM; 26.11.2019
comment
@DanielM?, = И & допустимы в запросах согласно спецификации, хотя на практике они широко используются для анализа пар имя-значение в запросе. Таким образом, они могут быть небезопасными как часть самих имен / значений. Вопрос о том, является ли это небезопасным или нет, остается вопросом мнения. - person Beejor; 05.01.2020
comment
Некоторые источники по запросу. (1) RFC 3986, раздел 3.4: [...] компоненты запроса часто используются для передачи идентифицирующей информации в форме пар «ключ = значение» [...] (2) WhatWG URL Spec, Sec. 6.2: Создание и преобразование объекта URLSearchParams в строку довольно просто: [...] params.toString() // "key=730d67" (3) Руководство по PHP, http-build-query: создание строки запроса в кодировке URL. [...] Приведенный выше пример выведет: 0=foo&1=bar[...] (4) Дж. Старр, Perishable Press: при создании веб-страниц часто необходимо добавлять ссылки, требующие параметризованных строк запроса. - person Beejor; 05.01.2020
comment
@Beejor: я создаю URL и использую '-' и ';' во время строительства. Это не веб-приложение, а мобильное приложение. Не веб-разработчик, и, следовательно, буду ли я в безопасности, если использую два вышеуказанных символа в свойстве Path? docs.microsoft.com/en- us / dotnet / api / - person karsnen; 15.02.2020
comment
@karsnen Это допустимые символы URL. Хотя, если используется для ссылки на пути в локальной файловой системе, имейте в виду, что некоторые системы запрещают использование определенных символов в именах файлов. Например, file: /// path / to / my: file.ext будет недопустимым на Mac. - person Beejor; 17.02.2020

Лучше оставить только некоторые символы (белый список) вместо удаления определенных символов (черный список).

Технически вы можете разрешить любой символ, если вы правильно его кодируете. Но, чтобы ответить в духе вопроса, вы должны разрешить только эти символы:

  1. Строчные буквы (преобразование верхнего регистра в нижний)
  2. Цифры от 0 до 9
  3. Тире - или подчеркивание _
  4. Тильда ~

Все остальное имеет потенциально особое значение. Например, вы можете подумать, что можете использовать +, но его можно заменить пробелом. & тоже опасно, особенно при использовании некоторых правил перезаписи.

Как и в случае с другими комментариями, ознакомьтесь со стандартами и спецификациями для получения полной информации.

person carl    schedule 29.03.2009
comment
Сегодня я обнаружил, что преиод - плохой выбор символа для использования в URL-безопасном кодировщике Base64, потому что будут те редкие случаи, когда ваши закодированные данные могут образовывать две последовательные точки (..), что важно в том смысле, что относится к родительскому каталогу. - person pohl; 04.05.2011
comment
@pohl: это проблема только в том случае, если ваш URL-адрес используется в качестве пути к файлу, либо в вашем коде, либо если ваш веб-сервер действительно пытается сопоставить URL-адрес с файлами перед пересылкой запроса в сценарий (к сожалению, очень часто). - person André Caron; 07.05.2011
comment
На самом деле, в нашем случае использование его в качестве пути к файлу было бы нормально, поскольку в файлах unix разрешено иметь несколько и даже последовательных точек в своих именах. Для нас проблема возникла в инструменте мониторинга под названием Site Scope, в котором есть ошибка (возможно, наивное регулярное выражение), и он сообщает о ложных ложных простоях. Что касается нас, мы застряли на старой версии Site Scope, команда администраторов отказывается платить за обновление, и у одного очень важного клиента есть Site Scope (не эквивалент), записанный в их контракт. По общему признанию, большинство из них не окажутся на моем месте. - person pohl; 07.05.2011
comment
Слава богу, что кто-то опубликовал список без особой болтовни. Что касается точки (.) - как сказал @pohl, не используйте ее! Вот еще один странный случай с IIS (не знаю, происходит ли это на других веб-серверах): если он находится в конце вашего URL-адреса, вы, скорее всего, получите ошибку 404 (он попытается найти [/ pagename] . страница) - person nikib3ro; 01.06.2012
comment
Можешь перефразировать Тебя лучше оставить? - person Peter Mortensen; 14.01.2021

Глядя на RFC3986 - Uniform Resource Identifier (URI): Generic Syntax, ваш вопрос вращается вокруг путь в 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 = unreserved / pct-encoded / sub-delims / ":" / "@"

Что разбивается на:

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

pct-encoded

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

":" / "@"

Или другими словами: вы можете использовать любой (не контрольный) символ из таблица ASCII, кроме /, ?, #, [ и ].

Это понимание поддерживается RFC1738 - Uniform Resource Locators (URL).

person Philzen    schedule 19.07.2014
comment
Это отличный пример теоретически правильного ответа, который приводит к проблемам в применении к реальному миру, в котором мы на самом деле живем. Это правда, что большинство этих персонажей не будут вызывать проблемы большую часть времени. Но в реальном мире существуют такие вещи, как прокси, маршрутизаторы, шлюзы, реле и т. Д., И все они любят проверять URL-адреса и взаимодействовать с ними способами, которые игнорируют теоретический стандарт. Чтобы избежать этих ловушек, вы в значительной степени ограничены тем, что избегаете всего, кроме буквенно-цифровых символов, тире, подчеркивания и точки. - person deltamind106; 14.12.2015
comment
@ deltamind106 Можете ли вы предоставить примеры и / или ссылки, чтобы прояснить, какие из этих символов, которые являются безопасными согласно RFC, на самом деле небезопасны? В своем ответе я предпочел бы придерживаться фактов, подкрепленных стандартами, и я буду рад обновить свой ответ, если вы сможете точно указать какие-либо факты, которые я, возможно, не учел. - person Philzen; 14.12.2015
comment
@ deltamind106 Я бы посоветовал нам попытаться заставить продукты соответствовать стандартам, а не запрещать разработчикам. Я считаю ваше предупреждение заслуженным, но мы должны внести свой вклад и сообщить поставщикам о несоответствии, если это необходимо. - person Lo-Tan; 11.05.2016
comment
@Philzen: я создаю URL и использую '-' и ';' во время строительства. Это не веб-приложение, а мобильное приложение. Не веб-разработчик, и, следовательно, буду ли я в безопасности, если использую два вышеуказанных символа в свойстве Path? docs.microsoft.com/en- us / dotnet / api / - person karsnen; 15.02.2020
comment
@karsnen Да, конечно, - и ; безопасны, это ясно сказано в моем ответе и RFC. - person Philzen; 22.02.2020

Из контекста, который вы описываете, я подозреваю, что то, что вы на самом деле пытаетесь сделать, называется «SEO-слагом». Лучшая общеизвестная практика для них:

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

Так, например, статья под названием «Использование! @% $ * Для представления ругательств в комиксах» получит фрагмент «использование-представлять-ругательства-комиксы».

person chaos    schedule 29.03.2009
comment
Действительно ли это хороший способ удалить эти стоп-слова из URL-адреса? Могут ли поисковые системы наказывать веб-сайт из-за этого? - person Paulo; 30.03.2009
comment
Обычно считается, что поисковые системы признают только некоторую часть URL-адреса и / или придают меньшее значение более поздним частям, поэтому, удаляя стоп-слова, вы делаете то, что делаете, максимально увеличивая количество ключевых слов, которые вы вставляете в свой URL-адрес, что у вас есть шанс на самом деле в рейтинге. - person chaos; 30.03.2009
comment
@chaos Вы по-прежнему рекомендуете удалить StopWord, если примете это во внимание: seobythesea .com / 2008/08 / google-stopword-patch Также не могли бы вы порекомендовать хороший список игнорируемых слов? Это лучший список, который я нашел до сих пор - link-assistant.com/ seo-stop-words.html - person nikib3ro; 01.06.2012
comment
@ kape123 Мне это не кажется хорошим списком. c и d - это языки программирования, и многие из этих слов также имеют большое значение. Я бы, вероятно, просто разделил основные: a, and, is, on, of, or, the, with. - person mpen; 02.02.2016

unreserved = АЛЬФА / ЦИФРА / "-" / "." / "_" / "~"

person LKK    schedule 01.12.2010
comment
Разве АЛЬФА не подразумевает ЦИФРУ? Я предполагаю, что АЛЬФА - это сокращение от буквенно-цифрового, а буквенно-цифровое означает прописные, строчные и цифры. - person Luc; 04.06.2013
comment
На самом деле альфа не означает буквенно-цифровую. Буквы и цифры - это две разные вещи, а буквенно-цифровая - их комбинация. Он мог бы написать свой ответ так: БУКВЕННО-ЦИФРОВЫЙ / - /. / _ / ~ - person MacroMan; 03.09.2013
comment
Обозначение ABNF для слова «незарезервировано» в RFC 3986 перечисляет их отдельно. - person Patanjali; 26.11.2015

Формат URI определен в RFC 3986. См. Подробности в разделе 3.3.

person joschi    schedule 29.03.2009

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

person mpen    schedule 29.03.2009
comment
Почему дефисы предпочтительнее подчеркивания? Какое объяснение? - person Peter Mortensen; 26.01.2021
comment
@PeterMortensen studiohawk.com.au/blog/. или, может быть, лучше: ecreativeim.com/blog/index.php/2011/03/30/ Google рассматривает дефис как разделитель слов, но не обрабатывает подчеркивание таким образом. Google рассматривает и подчеркивает как объединение слов, поэтому red_sneakers - это то же самое, что и redneakers для Google. - person mpen; 26.01.2021

У меня была похожая проблема. Я хотел иметь красивые URL-адреса и пришел к выводу, что я должен разрешать в URL-адресах только буквы, цифры и _.

Это нормально, но потом я написал красивое регулярное выражение и понял, что он распознает, что все символы UTF-8 не являются буквами в .NET, и был запутан. Похоже, это известная проблема для механизма регулярных выражений .NET. Итак, я пришел к такому решению:

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 characters, because
/// .NET implementation of regex do not handle Unicode characters. 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 "-";
    }
}
person Lubomir Toshev    schedule 30.09.2011
comment
Регулярные выражения .NET довольно хорошо поддерживают юникод. Вы должны использовать классы символов Юникода, например. \ p {L} для всех букв. См. msdn.microsoft.com/en-us/library/20bw873z.aspx #CategoryOrBlock - person TheCycoONE; 26.06.2013

Я обнаружил, что очень полезно закодировать свой URL-адрес в безопасный, когда я возвращал значение через Ajax / PHP в URL-адрес, который затем снова читался страницей.

Вывод PHP с кодировщиком URL для специального символа &:

// PHP returning the success information of an Ajax request
echo "".str_replace('&', '%26', $_POST['name']) . " category was changed";

// JavaScript sending the value to the 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);
person DIY-Forum    schedule 28.03.2015

Я думаю, вы ищете что-то вроде кодирования URL - кодирования URL так, чтобы он безопасно для использования в Интернете:

Вот ссылка на это. Если вам не нужны специальные символы, просто удалите те, которые требуют кодировки URL:

Справочник по кодированию URL-адресов HTML

person Andy White    schedule 29.03.2009

От 3 до 50 символов. Может содержать строчные буквы, цифры и специальные символы - точку (.), Тире (-), подчеркивание (_) и со ставкой (@).

person Ramji    schedule 23.02.2016
comment
Есть ссылки на это? - person dakab; 23.02.2016