Безопасные символы для дружественного 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, «символы» включают латинские символы, такие как çи õ?
— Мохамад

6
@ Мохамад: Нет, только ASCII, хотя поддержка UTF-8 улучшается.
— Дитрих Эпп

@Dietrich Epp, спасибо. Я думаю, это не должно иметь значения, если URL предназначен для оформления и в целях SEO, например: www.mysite.com/[postId]/post-title-with-ç-and-õ
— Мохамад

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

7
Ваши читатели португальцы, поэтому используйте португальские символы.
— Дитрих Эпп

107

Есть два набора символов, за которыми нужно следить: зарезервированный и небезопасный .

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

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

Знаки, которые обычно считаются небезопасными :

  • пространство (" ")
  • меньше чем и больше чем ("<>")
  • открывать и закрывать скобки ("[]")
  • открывать и закрывать фигурные скобки ("{}")
  • труба ("|")
  • обратная косая черта ("\")
  • каретка ("^")
  • процентов ("%")

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


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

Спасибо - я обновил ответ.
— Gary.Ray

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

6
Другие, похоже, не согласны с тем, что тильда ~небезопасна. Вы уверены, что это так?
— DRS

3
Белый список не так хорош, если работать с другими языками, кроме английского. У Unicode слишком много точек кода ОК. Поэтому внесение в черный список небезопасных, вероятно, будет проще всего реализовать в регулярных выражениях.
— Патанджали

41

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

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

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

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

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


15
Я обнаружил, что предварительным периодом является неправильный выбор символа для URL-безопасного кодера Base64, потому что будут те редкие случаи, когда ваши закодированные данные могут давать две последовательные точки (".."), что существенно в что это относится к родительскому каталогу.
— Пол

5
@pohl: это проблема только в том случае, если ваш URL-адрес используется в качестве пути к файлу, либо в вашем коде, либо если ваш веб-сервер на самом деле пытается сопоставить URL-адрес с файлами перед пересылкой запроса в сценарий (к сожалению, очень часто).
— Андре Карон

4
На самом деле, в нашем случае использовать его в качестве пути к файлу было бы нормально, поскольку в файлах unix разрешено иметь несколько и даже последовательные точки в именах. Для нас проблема возникла в инструменте мониторинга под названием Site Scope, в котором есть ошибка (возможно, наивное регулярное выражение), и она сообщала о ложных ложных простоях. Для нас мы застряли на старой версии Site Scope, команда администраторов отказывается платить за обновление, и один очень важный клиент имеет 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-адрес может быть «небезопасным», в зависимости от контекста. Например, file: /// URL-адрес, содержащий недопустимые символы имени файла, или компонент запроса, содержащий «?», «=» И «&», если они не используются в качестве разделителей. Правильная обработка этих случаев, как правило, зависит от ваших сценариев и может быть обойдена, но об этом нужно помнить.


Не могли бы вы предоставить какие-либо источники для вашего второго требования («Иногда безопасно»)? В частности, я считаю, что вы ошибаетесь, говоря, что =это небезопасно для запросов. Например, FIQL принимает знаки равенства и описывает себя как «дружественный к URI» и «оптимизированный и предназначенный для использования в компоненте запроса». В моей интерпретации RFC 3986 явно разрешает "=", "&", "+" и другие в запросах.
— DanielM

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

Некоторые источники по запросу. (1) RFC 3986, раздел 3.4: «[...] компоненты запроса часто используются для передачи идентифицирующей информации в виде пар« ключ = значение »[...]» (2) WhatWG URL Spec, Sec. 6.2: «Построить и структурировать объект URLSearchParams довольно просто: [...] params.toString() // "key=730d67"» (3) PHP Manual, http-build-query: «Создать строку запроса в кодировке URL. [...] Приведенный выше пример выведет: 0=foo&1=bar[...](4) Дж. Старр, Perishable Press: «При создании веб-страниц часто необходимо добавлять ссылки, которые требуют параметризованных строк запроса».
— Beejor

@Beejor: я создаю URL и использую '-' и ';' во время строительства. Это не веб-приложение, а мобильное приложение. Не веб-разработчик и, следовательно, буду ли я в безопасности, если я использую два вышеупомянутых символа в свойстве Path? docs.microsoft.com/en-us/dotnet/api/…
— karsnen

1
@karsnen Это действительные символы URL. Хотя, если используется для ссылки на пути в локальной файловой системе, имейте в виду, что некоторые системы запрещают определенные символы в именах файлов. Например, «file: /// path / to / my: file.ext» будет недопустимым на Mac.
— Beejor

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-закодировано / под-разделы / ":" / "@"

Который распадается на:

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

pct-encoded

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

":" / "@"

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

Это понимание поддерживается RFC1738 - Унифицированные указатели ресурсов (URL) .


2
Это отличный пример теоретически правильного ответа, который приводит к проблемам применительно к реальному миру, в котором мы на самом деле живем. Это правда, что большинство из этих персонажей не будут вызывать проблемы большую часть времени. Но в реальном мире существуют такие вещи, как прокси-серверы, маршрутизаторы, шлюзы, ретрансляторы и т. Д., Которые «любят» проверять URL-адреса и взаимодействовать с ними таким образом, который не учитывает теоретический стандарт. Чтобы избежать этих ловушек, вы в значительной степени ограничены избеганием всего, кроме буквенно-цифровых символов, тире, подчеркивания и точки.
— deltamind106

1
@ deltamind106 Можете ли вы предоставить примеры и / или ссылки, чтобы уточнить, какие из этих символов безопасны в соответствии с RFC, на самом деле это не так? Я бы предпочел придерживаться фактов, подкрепленных стандартами, в своем ответе, и я с удовольствием обновлю свой ответ, если вы сможете точно определить факты, которыми я мог пренебречь.
— Philzen

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

@Philzen: я создаю URL и использую '-' и ';' во время строительства. Это не веб-приложение, а мобильное приложение. Не веб-разработчик и, следовательно, буду ли я в безопасности, если я использую два вышеупомянутых символа в свойстве Path? docs.microsoft.com/en-us/dotnet/api/…
— karsnen

1
@karsnen Да, конечно -и ;безопасно, это то, что мой ответ и RFC ясно заявляет.
— Филзен

12

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


3
Разве «АЛЬФА» не означает «ЦИФРА»? Я предполагаю, что АЛЬФА - это сокращение от «буквенно-цифровой», а буквенно-цифровой означает прописные, строчные и цифры.
— Люк

11
На самом деле альфа не подразумевает буквенно-цифровой. Буква и цифра - это две разные вещи, а буквенно-цифровая - это сочетание этих вещей. Он мог бы написать свой ответ так: ALPHANUMERIC / "-" / "." / "_" / "~"
— 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, и, on, of, или,,, с.
— mpen


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 Encoding» - кодирование 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.