어떤 문자가 URL을 유효하지 않게합니까?
유효한 URL입니까?
example.com/file[/].html
http://example.com/file[/].html
어떤 문자가 URL을 유효하지 않게합니까?
유효한 URL입니까?
example.com/file[/].html
http://example.com/file[/].html
답변:
RFC 3986 ( 섹션 2 : 문자 참조)에 정의 된 일반적인 URI 에는 다음 84 자 중 하나가 포함될 수 있습니다.
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
이 목록에는 URI에서 이러한 문자가 발생할 수있는 위치가 나와 있지 않습니다.
다른 문자는 퍼센트 인코딩 ( %
hh
) 으로 인코딩해야합니다 . URI의 각 부분에는 퍼센트 인코딩 된 단어로 표현해야하는 문자에 대한 추가 제한 사항이 있습니다.
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
수락해야 할 것이 더 있습니까? (정확히
설명을 추가하고 위의 질문을 직접 해결하기 위해 URL과 URI에 문제를 일으키는 여러 클래스의 문자가 있습니다.
허용되지 않으며 URL / URI, 예약 문자 (아래 설명) 및 경우에 따라 문제가 발생할 수 있지만 "불명확 한"또는 "안전하지 않은"문자로 표시되어서는 안되는 문자가 있습니다. 문자가 제한되는 이유에 대한 설명은 RFC-1738 (URL) 및 RFC-2396 (URI) 에서 명확하게 설명되어 있습니다. 최신 RFC-3986 (RFC-1738로 업데이트)은 주어진 컨텍스트에서 허용되는 문자 구성을 정의하지만 이전 사양은 다음 규칙에 따라 허용되지 않는 문자에 대한보다 간단하고 일반적인 설명을 제공합니다.
URI 구문에서 허용되지 않는 US-ASCII 문자는 제외했습니다.
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
"#"문자는 조각 식별자에서 URI를 구분하는 데 사용되므로 제외됩니다. 퍼센트 문자 "%"는 이스케이프 문자의 인코딩에 사용되므로 제외됩니다. 즉, "#"및 "%"는 특정 컨텍스트에서 사용해야하는 예약 문자입니다.
현명하지 않은 문자 목록은 허용되지만 문제가 발생할 수 있습니다.
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
쿼리 구성 요소 내에 예약 되거나 URI / URL 내에 특별한 의미가있는 문자 :
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
위의 "예약 된"구문 클래스는 URI 내에서 허용되지만 일반 URI 구문의 특정 구성 요소 내에서는 허용되지 않는 문자를 나타냅니다. "예약 된"세트의 문자가 모든 컨텍스트에서 예약 된 것은 아닙니다 . 예를 들어, 호스트 이름은 선택적 사용자 이름을 포함 할 수 있으므로 ftp://user@hostname/
'@'문자가 특별한 의미 가있는 것과 같은 이름 일 수 있습니다 .
다음은 유효하지 않은 현명하지 않은 문자 (예 : '$', '[', ']')가 있고 올바르게 인코딩되어야하는 URL의 예입니다.
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
URI / URL의 문자 제한 중 일부는 프로그래밍 언어에 따라 다릅니다. 예를 들어, '|' URI 스펙에서 "unwise"로만 표시되었지만 (0x7C) 문자 는 Java java.net.URI 생성자 에서 URISyntaxException 을 발생 시키므로 URI와 같은 URL 은 허용되지 않으며 마치 URI 오브젝트 인스턴스에 Java를 사용 하는 것처럼 인코딩되어야 합니다.http://api.google.com/q?exp=a|b
http://api.google.com/q?exp=a%7Cb
?
은 쿼리 섹션 에서 훌륭 하지만 그 전에는 불가능하므로 @
이러한 목록에 속하지 않는다고 생각 합니다. 아, 그리고 %25
마지막 문자열 대신에 , 당신은 의미하지 %7C
않습니까?
여기에있는 기존 답변의 대부분은 다음과 같은 실제 주소 사용을 완전히 무시하기 때문에 비실용적입니다.
첫째, 용어로의 탈선. 이 주소 는 무엇입니까 ? 유효한 URL입니까?
역사적으로 대답은 "아니오"였습니다. 에 따르면RFC 3986 2005 년부터 이러한 주소는 URI가 아니므로 URL 이 URI의 유형 이므로 URL 이 아닙니다 . 2005 IETF 표준의 용어에 따라 RFC 3987에 정의 된 대로 IRI (Internationalized Resource Identifiers)를 적절하게 호출해야합니다. RFC 3987 은 기술적으로 URI가 아니지만 IRI에서 ASCII가 아닌 모든 문자를 퍼센트 인코딩하여 간단히 URI로 변환 할 수 있습니다. .
현대의 사양에 따라 대답은 "예"입니다. 그만큼WHATWG 생활 수준은 단순히 이전에 "URL을"로 "URI를"또는 "아이리스"라는 것 모든 것을 분류한다. 이는 스펙을 읽지 않은 일반 사람들이 스펙의 목표 중 하나 인 "URL"이라는 단어를 사용하는 방식과 스펙 용어를 정렬합니다 .
"URL"의이 새로운 의미에 따라 어떤 문자가 허용됩니까? 쿼리 문자열 및 경로와 같은 URL의 많은 부분에서 임의의 것을 사용할 수 있습니다. "URL 단위" 를 사용할 수 있습니다.
"URL 코드 포인트"란 무엇입니까?
URL 코드 포인트 + 0,021 U (!) + 0024 U ($) + 0026 U () + 0027 U ( '), U + 0028 LEFT PARENTHESIS, U + 0029 RIGHT PARENTHESIS, U +, ASCII의 영숫자 002A (*), U + 002B (+), U + 002C (,), U + 002D (-), U + 002E (.), U + 002F (/), U + 003A (:), U + 003B (;), U + 003D (=), U + 003F (?), U + 0040 (@), U + 005F (_), U + 007E (~) 및 U + 00A0 ~ U 범위의 코드 포인트 + 10FFFD, 대리 및 비 문자 제외.
(주 "URL 코드 포인트"의 목록에 포함되지 않습니다 %
,하지만%
의는 "URL 코드 단위"에서 허용되는 경우 그들이 퍼센트 인코딩 시퀀스의있는 거 부분.)
스펙 이이 세트에 없는 문자의 사용을 허용하는 유일한 장소 는 IPv6 주소 와 문자 로 묶인 호스트 입니다. URL의 다른 곳에서는 URL 단위 또는 더 제한적인 문자 집합이 허용됩니다.[
]
역사를 위해서, 그리고 여기에 대한 답변의 다른 곳에서 완전히 탐구되지 않았으므로, 더 오래된 사양 쌍에서 검사가 허용되었습니다.
우선, 두 가지 유형의 RFC 3986 예약 문자가 있습니다 .
:/?#[]@
RFC 3986에 정의 된 URI에 대한 일반 구문의 일부입니다.!$&'()*+,;=
는 RFC의 일반 구문에 포함되지 않지만 특정 URI 체계의 구문 구성 요소로 사용하도록 예약되어 있습니다. 예를 들어, 세미콜론 및 쉼표의 신택스의 일부로서 사용되는 데이터의 URI 와 &
와 =
유비쿼터스의 일부로서 사용된다 ?foo=bar&qux=baz
(질의 스트링의 형식 되지 RFC 3986에 의해 특정).위의 예약 문자는 인코딩 목적없이 URI에서 합법적으로 사용되어 구문 목적으로 사용되거나 데이터의 문자 그대로 문자 그대로 사용되어 구문 목적으로 사용되는 문자로 잘못 해석 될 수없는 경우가 있습니다. 예를 들어 /
URL에 구문 의미가 있지만 쿼리 문자열 에는 의미 가 없으므로 쿼리 문자열에서 인코딩되지 않은 상태로 사용할 수 있습니다 .
RFC 3986은 또한 예약되지 않은 문자를 지정 하며 인코딩없이 데이터를 나타내는 데 항상 간단하게 사용할 수 있습니다.
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
마지막으로 %
문자 자체는 퍼센트 인코딩에 허용됩니다.
잎 만 다음 ASCII 문자 그 금지 의 URL에 표시 :
"<>\^`{|}
ASCII의 다른 모든 문자는 합법적으로 URL에 표시 될 수 있습니다.
그런 다음 RFC 3987은 예약되지 않은 문자 세트를 다음과 같은 유니 코드 문자 범위로 확장합니다.
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
구 스펙에서 이러한 블록 선택은 최신 유니 코드 블록 정의를 고려할 때 기괴하고 임의적입니다 . RFC 3987이 작성된 이후 10 년 동안 블록이 추가 되었기 때문일 수 있습니다.
마지막으로, 어떤 문자가 URL의 특정 부분에서만 유효한 것이기 때문에, 어떤 문자가 URL에 합법적으로 나타날 수 있는지 아는 것만으로는 주어진 문자열이 유효한 URL인지 아닌지를 인식하기에 충분하지 않다는 점에 주목할 가치가 있습니다. 예를 들어, 예약 문자 [
와는 ]
합법적 같은 URL에서의 IPv6 리터럴 호스트의 일환으로 / foo는 HTTP : // [417A 1080 :: 8 : 800 : 200C] 그렇게하지만, 다른 상황에서 불법이다 OP의 예 http://example.com/file[/].html
는 불법입니다.
보충 질문 www.example.com/file[/].html
에서 유효한 URL 인지 물었습니다 .
URL이 URI 유형이고 유효한 URI와 같은 체계가 있어야하므로 해당 URL이 유효하지 않습니다 http:
( RFC 3986 참조 ).
http://www.example.com/file[/].html
유효한 URL 인지 묻는 경우 대괄호 문자가 유효하지 않기 때문에 대답은 여전히 아니오입니다.
대괄호 문자는 다음 형식으로 URL에 예약되어 있습니다 http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(예 : 호스트 이름 대신 IPv6 리터럴)
문제를 완전히 이해하려면 RFC 3986을주의 깊게 읽으십시오.
Unwise
URI에 대해 매우 심각하게 생각하지만 URL 라이브러리에는 적합합니다. 그것은 무시할 플래그가 없다는 것입니다 Unwise
. URL에 대해 Rust lang이 무엇인지 확인해야합니다 (브라우저 용으로 제작되었으므로 궁금합니다). 그러나 대부분의 브라우저는 "[", "]"를 행복하게 전달합니다. 그래서 이론적으로 C / C ++로 말한 것처럼 하위 / 슈퍼이지만 현실은 그렇게 사실이 아닙니다. 그것은 수퍼 / 서브셋의 사양과 의미의 해석에 크게 의존한다.
URI에서 사용할 수있는 모든 유효한 문자 ( URL 은 URI 유형 임 )는 RFC 3986에 정의되어 있습니다.
다른 모든 문자는 먼저 "URL 인코딩"인 경우 URL에 사용될 수 있습니다. 여기에는 특정 "코드"에 대한 유효하지 않은 문자 (일반적으로 퍼센트 기호 (%)와 16 진수)가 변경됩니다.
HTML URL 인코딩 참조 링크 에는 유효하지 않은 문자에 대한 인코딩 목록이 포함되어 있습니다.
여러 유니 코드 문자 범위는 유효한 HTML5 이지만 여전히 사용하지 않는 것이 좋습니다.
예를 들어 href
문서는 http://www.w3.org/TR/html5/links.html#attr-hyperlink-href 라고 말합니다 .
및 영역 요소의 href 속성은 공백으로 둘러싸 일 수있는 유효한 URL 값을 가져야합니다.
그런 다음 "유효한 URL"의 정의는 http://url.spec.whatwg.org/를 가리키며 이는 다음을 목표로합니다.
RFC 3986 및 RFC 3987을 최신 구현에 맞추고 프로세스에서 사용하지 마십시오.
이 문서는 URL 코드 포인트 를 다음과 같이 정의합니다 .
ASCII 영숫자, "!", "$", "&", " '", "(", ")", "*", "+", ",", "-", ".", "/" , ":", ";", "=", "?", "@", "_", "~"및 U + 00A0 ~ U + D7FF, U + E000 ~ U + FDCF 범위의 코드 포인트 , U + FDF0 ~ U + FFFD, U + 10000 ~ U + 1FFFD, U + 20000 ~ U + 2FFFD, U + 30000 ~ U + 3FFFD, U + 40000 ~ U + 4FFFD, U + 50000 ~ U + 5FFFD, U + 60000 ~ U + 6FFFD, U + 70000 ~ U + 7FFFD, U + 80000 ~ U + 8FFFD, U + 90000 ~ U + 9FFFD, U + A0000 ~ U + AFFFD, U + B0000 ~ U + BFFFD, U + C0000 U + CFFFD로, U + D0000에서 U + DFFFD로, U + E1000에서 U + EFFFD로, U + F0000에서 U + FFFFD로, U + 100000에서 U + 10FFFD로.
"URL 코드 포인트"라는 용어는 다음 명령문에서 사용됩니다.
c가 URL 코드 포인트가 아니고 "%"가 아닌 경우 구문 분석 오류입니다.
스키마, 권한, 상대 경로, 쿼리 및 조각 상태를 포함하여 구문 분석 알고리즘의 여러 부분에서 기본적으로 전체 URL.
또한 유효성 검사기 http://validator.w3.org/는와 같은 "你好"
URL을 전달하며 공백과 같은 문자가 포함 된 URL은 전달하지 않습니다."a b"
물론 Stephen C가 언급했듯이 문자뿐만 아니라 컨텍스트에 관한 것입니다. 전체 알고리즘을 이해해야합니다. 그러나 "URL 코드 포인트"클래스는 알고리즘의 핵심 포인트에 사용되므로 사용 가능한 항목에 대한 좋은 아이디어를 제공합니다.
참조 : URL에 유니 코드 문자
URL을 문자열로 나누려면 문자를 선택해야하므로 URL에서 찾을 수없는 문자 목록을 직접 결정했습니다.
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
따라서 가능한 선택은 개행, 탭, 공백, 백 슬래시 및 "<>{}^|
입니다. 스페이스 나 줄 바꿈과 함께 갈 것 같아요. :)
귀하의 질문에 대한 답변은 아니지만 url의 유효성을 검사하는 것은 실제로 심각한 피타입니다. 도메인 이름을 확인하고 url의 쿼리 부분을 그대로 두는 것이 좋습니다. 그게 내 경험입니다. 또한 URL을 핑 (ping)하여 올바른 응답이 발생하는지 확인하지만 그러한 간단한 작업에는 너무 많은 것일 수 있습니다.
URL을 감지하는 정규식은 풍부합니다 .Google :)
오래된 http (0.9, 1.0, 1.1) 요청 및 응답 리더 / 라이터를 구현하고 있습니다. 요청 URI가 가장 문제가되는 곳입니다.
RFC 1738, 2396 또는 3986을 그대로 사용할 수는 없습니다. 더 많은 문자를 허용하는 오래된 HTTP 클라이언트와 서버가 많이 있습니다. 그래서 우연히 게시 된 웹 서버 액세스 로그를 기반으로 조사했습니다."GET URI HTTP/1.0" 200
.
URI에서 다음과 같은 비표준 문자가 자주 사용되는 것으로 나타났습니다.
\ { } < > | ` ^ "
이 문자들은 RFC 1738 에서 안전하지 않은 것으로 설명되었습니다 .
모든 오래된 HTTP 클라이언트 및 서버와 호환 되려면 이 문자 를 허용해야합니다 요청 URI에서 합니다.
이 연구에 대한 자세한 내용은 http-og를 참조하십시오 .
텍스트의 URL을 앵커 태그로 변환하는 PHP에 대한 몇 가지 정규식을 생각해 냈습니다. (먼저 모든 www. url을 http : //로 변환 한 다음 https? : //가있는 모든 url을 a href = ... html 링크로 변환합니다
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string)
);