친숙한 URL을위한 안전한 문자 [닫힘]


168

기사가있는 웹 사이트를 만들어야하며, URL이 포함 된 페이지의 URL과 같이 친숙한 URL을 만들고 싶습니다.

제목 : 기사 테스트

되어야합니다 : http://www.example.com/articles/article_test.

물론 내가 좋아하는 제목에서 일부 문자를 제거해야 ?하거나 #,하지만 확실히 제거 할 것 아니에요.

어떤 캐릭터가 보관하기에 안전한지 말해 줄 수 있습니까?


비슷한 질문이 있습니다 . 그것을 확인하십시오. 유용한 답변도 있습니다 (많은 답변이 있습니다).
Rook

답변:


210

RFC 3986의 2.3 절을 인용하면 :

"URI에서 허용되지만 예약 된 목적이없는 문자는 예약되지 않은 문자라고합니다. 대문자 및 소문자, 십진수, 하이픈, 마침표, 밑줄 및 물결표를 포함합니다."

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

RFC 3986에는 이전 문장 부호보다 예약 된 문장 부호가 적습니다. RFC 2396 .


@Skip Head, "characters"에는 라틴 인코딩 문자 çõ?
Mohamad

6
@Mohamad : 아니요. ASCII 만 가능하지만 UTF-8 지원이 향상되고 있습니다.
Dietrich Epp 2016 년

@ Dietrich Epp, 감사합니다. URL이 장식 및 SEO 목적을위한 것인지 여부는 중요하지 않습니다. www.mysite.com/[postId]/post-title-with-ç-and-õ
Mohamad

1
@Mohamad : 마지막 부분은로 바뀌지 post-title-with-%C3%A7-and-%C3%B5만 사용자의 위치 표시 줄에는 여전히로 표시됩니다 post-title-with-ç-and-õ.
Dietrich Epp 2016 년

7
독자는 포르투갈어이므로 포르투갈어 문자를 사용하십시오.
Dietrich Epp 2016 년

107

주의해야 할 문자 세트는 reservedunsafe 입니다.

예약 문자는 다음과 같습니다

  • 앰퍼샌드 ( "&")
  • 달러 ( "$")
  • 더하기 부호 ( "+")
  • 반점 (",")
  • 슬래시 ( "/")
  • 콜론 ( ":")
  • 세미콜론 ( ";")
  • 같음 ( "=")
  • 물음표 ("?")
  • 'At'기호 ( "@")
  • 파운드 ( "#").

일반적으로 안전하지 않은 것으로 간주되는 문자 는 다음과 같습니다.

  • 우주 (" ")
  • 보다 작거나 큼 ( "<>")
  • 열기 및 닫기 괄호 ( "[]")
  • 열기 및 닫기 괄호 ( "{}")
  • 파이프 ( "|")
  • 백 슬래시 ( "\")
  • 캐럿 ( "^")
  • 퍼센트 ( "%")

나는 하나 이상을 잊어 버렸을 수 있으며, 이는 칼 V의 대답을 에코합니다. 장기적으로는 서버 및 시스템에서 허용되지 않는 문자를 유지하려고 시도하는 대신 허용되는 문자의 "화이트리스트"를 사용한 다음 문자열을 인코딩하는 것이 좋습니다.


#이름 속성 또는 id 속성 (sans #-symbol) 과 일치하는 HTML 요소를 하나 생성하여 특정 페이지의 책갈피에 사용되는 예약 문자 입니다.
TheLonelyGhost

감사합니다-답변을 업데이트했습니다.
Gary.Ray

물음표는 예약 된 것과 안전하지 않은 것으로 여기에 표시됩니다. 예약 된 것으로 만 생각하지만 잘못되었을 수도 있습니다.
Jonathan Basile

6
다른 사람들은 물결표 ~가 안전 하지 않다는 데 동의하지 않는 것 같습니다 . 확실합니까?
drs

3
영어 이외의 언어를 처리하는 경우 허용 목록이 좋지 않습니다. 유니 코드에는 OK 코드 포인트가 너무 많습니다. 따라서 안전하지 않은 것을 블랙리스트에 올리는 것이 정규식으로 구현하는 것이 가장 쉬운 방법 일 것입니다.
Patanjali

41

특정 문자 (블랙리스트)를 제거하는 대신 일부 문자 (화이트리스트) 만 유지하는 것이 가장 좋습니다.

제대로 인코딩하는 한 기술적으로 모든 문자를 허용 할 수 있습니다. 그러나 질문의 ​​정신으로 대답하려면 다음 문자 만 허용해야합니다.

  1. 소문자 (대문자를 소문자로 변환)
  2. 숫자, 0 ~ 9
  3. 대시 또는 밑줄 _
  4. 틸드 ~

다른 모든 것에는 잠재적으로 특별한 의미가 있습니다. 예를 들어 +를 사용할 수 있다고 생각할 수 있지만 공백으로 바꿀 수 있습니다. &는 특히 일부 다시 쓰기 규칙을 사용하는 경우에도 위험합니다.

다른 의견과 마찬가지로 자세한 내용은 표준 및 사양을 확인하십시오.


15
내가 오늘 발견 한 기간은 URL 안전 Base64 인코더에 사용할 문자를 잘못 선택하는 것입니다. 인코딩 된 데이터가 연속 된 두 개의 점 ( "..")을 생성 할 수있는 드문 경우가 있기 때문입니다. 그것은 그것이 부모 디렉토리를 참조한다는 것입니다.
pohl

5
@pohl : 코드에서 URL이 파일 경로로 사용되거나 웹 서버가 실제로 요청을 스크립트에 전달하기 전에 URL을 파일에 매핑하려고 시도하는 경우에만 문제가됩니다 (불행히도 매우 일반적입니다).
André Caron

4
실제로 우리의 경우 파일 경로로 사용하는 것이 좋습니다. 유닉스 파일의 경우 이름에 여러 점, 심지어는 점이있을 수 있기 때문입니다. 우리에게 문제는 사이트 스코프 (Site Scope)라는 모니터링 도구에서 발생했으며 버그 (아마도 순진한 정규식)가 있으며 가짜 잘못된 다운 타임을보고했습니다. 우리에게는 이전 버전의 Site Scope가 붙어 있으며 관리자 팀은 업그레이드 비용을 지불하지 않으며 매우 중요한 고객 중 하나가 계약에 Site Scope (동등하지 않음)를 작성했습니다. 분명히, 대부분 내 신발에 자신을 찾을 수 없습니다.
pohl

8
많은 사람이 목록을 많이 작성하지 않은 채 하나님 께 감사드립니다. @pohl이 말했듯이 점 (.)은 사용하지 마십시오! IIS의 또 다른 이상한 경우가 있습니다 (다른 웹 서버에서 발생하는지 알지 못함). URL 끝에 있으면 404 오류가 발생합니다 ([/ pagename]을 검색하려고 시도합니다) 페이지)
nikib3ro 2016 년

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, Sec 3.4 : "[...] 쿼리 구성 요소는 종종 'key = value'쌍 [...] 형식으로 식별 정보를 전달하는 데 사용됩니다."(2) WhatWG URL Spec, Sec. 6.2 : "URLSearchParams 객체를 구성하고 params.toString() // "key=730d67"문자열 화하는 것은 매우 간단합니다 : [...] "(3) PHP Manual, http-build-query : "URL 인코딩 된 쿼리 문자열 생성 [...] 위 예제는 다음과 같이 출력됩니다 : 0=foo&1=bar[...]"(4) J. Starr, 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 (Uniform Resource Identifier) : 일반 구문 의 주위에 당신의 질문의 공전 경로 는 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 (Uniform Resource Locator)에 의해 뒷받침됩니다 .


2
이것은 이론적으로 올바른 답의 훌륭한 예이며, 실제로 우리가 살고있는 실제 세계에 적용될 때 문제를 일으 킵니다. 대부분의 캐릭터가 대부분의 경우 문제를 일으키지 않을 것입니다. 그러나 프록시, 라우터, 게이트웨이, 릴레이 등과 같은 현실 세계에는 이론적 표준을 무시하는 방식으로 URL을 검사하고 상호 작용하는 "사랑"이 있습니다. 이러한 함정을 피하려면 영숫자, 대시, 밑줄 및 마침표를 제외한 모든 항목을 이스케이프 처리해야합니다.
deltamind106

1
@ deltamind106 RFC에 따라 안전하지 않은 문자를 명확히하기 위해 예제 및 / 또는 참조를 제공 할 수 있습니까? 나는 내 대답에 표준으로 뒷받침되는 사실을 고수하고 싶습니다. 내가 무시한 사실을 정확히 지적 할 수 있다면 내 대답을 업데이트하게되어 기쁩니다.
Philzen

2
@ deltamind106 개발자들에게하지 말고 제품이 표준을 따르도록 노력하십시오. 귀하의 경고가 유력하다고 생각하지만 필요한 경우 공급 업체에 부적합 사항을보고하는 데 최선을 다해야합니다.
Lo-Tan

@Philzen : URL을 구성하고 있으며 '-'와 ';'을 사용합니다. 건설 중. 웹 앱이 아니라 모바일 앱입니다. 웹 개발자가 아니므로 Path 속성에 위의 두 문자를 사용하면 안전합니까? docs.microsoft.com/en-us/dotnet/api/…
karsnen

1
@karsnen 예를 물론 -하고 ;내 대답과 RFC 명확하게 진술 무슨 그, 안전합니다.
Philzen

12

예약되지 않음 = ALPHA / DIGIT / "-"/ "." / "_"/ "~"


3
"ALPHA"가 "DIGIT"을 의미하지 않습니까? ALPHA는 "영숫자"의 줄임말이고 영숫자는 대문자, 소문자 및 숫자를 의미합니다.
Luc

11
실제로 알파는 영숫자를 의미하지 않습니다. 알파와 숫자는 서로 다른 두 가지이며 영숫자는 그러한 것들의 조합입니다. 그는 자신의 대답을 다음과 같이 쓸 수있었습니다 : ALPHANUMERIC / "-"/ "." / "_"/ "~"
MacroMan

1
RFC 3986의 '예약되지 않은'에 대한 ABNF 표기법에 따로 나열되어 있습니다.
Patanjali

11

당신이 묘사하는 맥락에서, 당신이 실제로하려는 것은 'SEO 슬러그'라고 생각합니다. 이를위한 가장 일반적인 알려진 방법은 다음과 같습니다.

  1. 소문자로 변환
  2. az 및 0-9 이외의 모든 문자 시퀀스를 하나의 하이픈 (-)으로 변환합니다 (밑줄이 아님).
  3. URL에서 '중지 단어', 즉 'a', 'an'및 'the'와 같이 의미가 색인 할 수없는 단어를 제거하십시오. 광범위한 목록을위한 Google '중지 단어'

예를 들어, "만화에서 욕설을 표현하기 위해! @ % $ *의 사용법"이라는 제목의 기사는 "usage-represent-swearing-comics"의 슬로건을 얻게됩니다.


URL에서 이러한 "중지 단어"를 제거하는 것이 정말 좋은 방법입니까? 이 때문에 검색 엔진이 웹 사이트에 불이익을 주나요?
Paulo

검색 엔진은 일반적으로 URL의 일부만 인식하고 /하거나 이후 부분에 대한 중요성을 줄인 것으로 여겨지므로 중지 단어를 제거하여 URL에 포함 된 키워드의 수를 최대화하는 것이 좋습니다. 실제로 순위를 매겼습니다.
혼돈

1
@chaos 다음을 고려하면 StopWord를 제거하는 것이 좋습니다. seobythesea.com/2008/08/google-stopword-patent 또한 훌륭한 단어 목록을 추천 할 수 있습니까? 이것은 내가 지금까지 찾은 최고의 목록입니다 -link-assistant.com/seo-stop-words.html
nikib3ro

@ kape123 그것은 나에게 아주 좋은 목록처럼 보이지 않습니다. "c"와 "d"는 프로그래밍 언어이며, 다른 많은 단어들도 중요하게 보입니다. 나는 아마도 기본 것들을 제거 할 것입니다 : a, and, is, on, of, or, with.
mpen

6

URI의 형식은 RFC 3986에 정의되어 있습니다. 자세한 내용은 3.3 절을 참조하십시오.


6

SEO 관점에서 밑줄보다 하이픈이 선호됩니다. 소문자로 변환하고 모든 아포스트로피를 제거한 다음 영숫자가 아닌 모든 문자열을 단일 하이픈으로 바꿉니다. 시작과 끝에서 초과 하이픈을 자릅니다.


3

비슷한 문제가 있었는데 예쁜 URL을 원했고 URL에 문자, 숫자 및-만 허용해야한다는 결론에 도달했습니다. 괜찮습니다. 그런 다음 멋진 정규 표현식을 작성했으며 모든 UTF8 문자가 .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 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 정규 표현식은 실제로 유니 코드를 아주 잘 지원합니다. 모든 문자에 대해 유니 코드 문자 클래스 (예 : \ p {L})를 사용해야합니다. 참조 msdn.microsoft.com/en-us/library/20bw873z.aspx#CategoryOrBlock
TheCycoONE

1

ajax / php를 통해 값을 URL로 반환 할 때 내 URL을 안전한 URL로 인코딩하는 것이 매우 유용하다는 것을 알았습니다.

특수 문자 및 URL 인코더를 사용하여 PHP 출력

//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);

누구나 내 작은 코드 추출이 유용하다는 것을 알기를 바랍니다! :)



-4

3 ~ 50 자 소문자, 숫자 및 특수 문자 (점 (.), 대시 (-), 밑줄 (_) 및 속도 (@))를 포함 할 수 있습니다.


4
모든 이에 대한 참조?
dakab
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.