Các ký tự được phép trong một URL


190

Có ai biết danh sách đầy đủ các ký tự có thể được sử dụng trong GET mà không được mã hóa không? Hiện tại tôi đang sử dụng AZ az và 0-9 ... nhưng tôi đang tìm hiểu danh sách đầy đủ.

Tôi cũng quan tâm đến việc có một đặc điểm kỹ thuật nào được phát hành cho sự bổ sung sắp tới của url tiếng Trung, tiếng Ả Rập (vì rõ ràng điều đó sẽ có tác động lớn đến câu hỏi của tôi)


5
Các ký tự được phép trong URI được bảo lưu !*'();:@&=+$,/?#[]hoặc không được bảo vệ A-Za-z0-9_.~-(hoặc ký tự phần trăm %là một phần của mã hóa phần trăm)
Mikl

1
Trong MySQL tôi sử dụng điều này REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'để tìm chuỗi URL có các ký tự xấu. Có lẽ nó cũng hữu ích cho người khác.
Mikl

@Mikl: Điều đó hầu như không giống như một biểu thức thông thường.
Jens Mander

Câu trả lời:


180

Từ đặc tả RFC 1738 :

Do đó, chỉ các chữ số, ký tự đặc biệt " $-_.+!*'()," và các ký tự dành riêng được sử dụng cho mục đích dành riêng của chúng có thể được sử dụng không được mã hóa trong một URL.

EDIT: Như @Jukka K. Korpela chỉ ra chính xác, RFC này đã được cập nhật bởi RFC 3986 . Điều này đã mở rộng và làm rõ các ký tự hợp lệ cho máy chủ, tiếc là nó không dễ dàng sao chép và dán, nhưng tôi sẽ làm hết sức mình.

Theo thứ tự khớp đầu tiên:

host        = IP-literal / IPv4address / reg-name

IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"

IPvFuture   = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

IPv6address =         6( h16 ":" ) ls32
                  /                       "::" 5( h16 ":" ) ls32
                  / [               h16 ] "::" 4( h16 ":" ) ls32
                  / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
                  / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
                  / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
                  / [ *4( h16 ":" ) h16 ] "::"              ls32
                  / [ *5( h16 ":" ) h16 ] "::"              h16
                  / [ *6( h16 ":" ) h16 ] "::"

ls32        = ( h16 ":" h16 ) / IPv4address
                  ; least-significant 32 bits of address

h16         = 1*4HEXDIG 
               ; 16 bits of address represented in hexadecimal

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

dec-octet   = DIGIT                 ; 0-9
              / %x31-39 DIGIT         ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT     ; 200-249
              / "25" %x30-35          ; 250-255

reg-name    = *( unreserved / pct-encoded / sub-delims )

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"     <---This seems like a practical shortcut, most closely resembling original answer

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

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

pct-encoded = "%" HEXDIG HEXDIG

5
Dấu gạch chéo @Tim là một ký tự dành riêng, do đó, nếu nó đang được sử dụng cho mục đích dành riêng của nó (đường dẫn phân định, phân định giao thức ...), thì nó không cần thoát. Nếu không, nó làm.
Myles

4
Các quy tắc cú pháp chung của RFC 1738 đã bị lỗi thời vào năm 1998.
Jukka K. Korpela

3
@Myles, STD 66 (= RFC 3986) được đề cập trong các câu trả lời khác. Liệu nội dung câu trả lời có đúng hay không là một vấn đề khác nhau; Tôi không nghĩ bất kỳ câu trả lời nào mô tả chính xác danh sách đầy đủ.
Jukka K. Korpela

4
Và bạn có thể thêm danh sách các A-Za-z0-9_.-~ký tự không được giám sát và dành riêng vào đầu câu trả lời này. !*'();:@&=+$,/?#[]Nó có thể tiết kiệm thời gian cho mọi người
Mikl

2
@basZero Tôi xin lỗi bạn thấy nó khó hiểu, nhưng câu trả lời đầy đủ không đơn giản. Câu trả lời cho câu hỏi của bạn là không, vì nó là một ký tự dành riêng như được nêu bởi:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles

42

Các ký tự được phép trong URI được bảo lưu hoặc không được bảo vệ (hoặc ký tự phần trăm là một phần của mã hóa phần trăm)

http://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_char character

cho biết đây là các ký tự không được giám sát RFC 3986 (giây 2.3) cũng như các ký tự dành riêng (giây 2.2) nếu chúng cần giữ lại ý nghĩa đặc biệt của chúng. Và cũng là một ký tự phần trăm như là một phần của mã hóa phần trăm.


7
Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi.
jaestevan

@jaestevan Trích dẫn từ tài liệu được liên kết:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl

26

Danh sách đầy đủ của 66 nhân vật không được giám sát có trong RFC3986, tại đây: http://tools.ietf.org/html/rfc3986#section-2.3

Đây là bất kỳ ký tự nào trong tập regex sau:

[A-Za-z0-9_.\-~]

2
Bạn có thể sử dụng những người dành riêng quá.
Qwerty

RFC1738 lỗi thời được liệt kê {}^\~backticklà không an toàn. Và RFC3986 liệt kê \ là không an toàn vì hệ thống tệp. Điều này có nghĩa là {}^có thể được sử dụng là tốt.
mgutt

Vì vậy, nếu bạn đang cố gắng tìm phần cuối của một url trong chuỗi (tôi là), tốt nhất bạn nên tuân theo các tiêu chuẩn lỗi thời trong câu trả lời được chấp nhận ... Nếu bạn xác thực url của bạn, bạn nên sử dụng bộ ký tự cho câu trả lời này
ashleedawg

Cẩn thận, bạn đã viết đây là một lớp nhân vật biểu hiện thông thường. Hãy chắc chắn thoát khỏi -hoặc đặt nó ở đầu hoặc cuối của lớp nhân vật, bởi vì [.-~]thực sự chứa tất cả các ký tự ASCII từ 46 đến 126.
kwl

19

Tôi đã kiểm tra nó bằng cách yêu cầu trang web của tôi (apache) với tất cả các ký tự có sẵn trên bàn phím tiếng Đức của tôi dưới dạng tham số URL:

http://example.com/?^1234567890ß´qwertzuiopü+asdfghjklöä#<yxcvbnm,.-°!"§$%&/()=? `QWERTZUIOPÜ*ASDFGHJKLÖÄ\'>YXCVBNM;:_²³{[]}\|µ@€~

Chúng không được mã hóa:

^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-!/()=?`*;:_{}[]\|~

Không được mã hóa sau urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Không được mã hóa sau rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Lưu ý: Trước khi rawurlencode()mã hóa PHP 5.3.0 ~RFC 1738 . Nhưng điều này đã được thay thế bởi RFC 3986 vì vậy nó an toàn để sử dụng ngay bây giờ. Nhưng tôi không hiểu tại sao ví dụ {}được mã hóa thông qua rawurlencode()vì chúng không được đề cập trong RFC 3986.

Một thử nghiệm bổ sung tôi đã thực hiện liên quan đến tự động liên kết trong các văn bản thư. Tôi đã kiểm tra Mozilla Thunderbird, aol.com, triển vọng.com, gmail.com, gmx.de và yahoo.de và họ đã liên kết đầy đủ các URL có chứa các ký tự này:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~+#,%&=*;:@

Tất nhiên, ?cũng được liên kết, nhưng chỉ khi nó được sử dụng một lần.

Một số người bây giờ sẽ đề nghị chỉ sử dụng rawurlencode()ký tự, nhưng bạn đã bao giờ nghe nói rằng ai đó có vấn đề khi mở các trang web này chưa?

Dấu hoa thị
http://wayback.archive.org/web/*/http://google.com

Đại tá https://en.wikipedia.org/wiki/Wikipedia: About

Cộng với
https://plus.google.com/+google

Tại dấu hiệu, dấu hai chấm, dấu phẩy và dấu chấm than
https: //www.google.com/maps/place/USA/@36.2218457, ...

Do đó, các ký tự này có thể được sử dụng không bị mã hóa mà không gặp vấn đề gì. Tất nhiên bạn không nên sử dụng &;vì trình tự mã hóa như thế nào &amp;. Lý do tương tự là hợp lệ %vì nó được sử dụng để mã hóa ký tự nói chung. Và =vì nó gán một giá trị cho một tên tham số.

Cuối cùng tôi sẽ nói nó ổn khi sử dụng những thứ chưa được mã hóa này:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@

Nhưng nếu bạn mong đợi các URL được tạo ngẫu nhiên, bạn không nên sử dụng .!, vì những URL đó đánh dấu kết thúc câu và một số ứng dụng thư sẽ không tự động liên kết char cuối cùng của url. Thí dụ:

Visit http://example.com/foo=bar! !

Cách tiếp cận thực tế - công việc tốt. Đang tìm kiếm danh sách cuối cùng của bạn - +đặc biệt là dấu hiệu :-D
Oliver

12

Từ đây

Do đó, chỉ các chữ số, các ký tự đặc biệt $-_.+!*'(), và ký tự dành riêng được sử dụng cho mục đích dành riêng của chúng có thể được sử dụng không được mã hóa trong một URL.



5

RFC3986 định nghĩa hai bộ ký tự bạn có thể sử dụng trong URI:

  • Nhân vật dành riêng ::/?#[]@!$&'()*+,;=

    dành riêng = gen-delims / sub delims

    gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

    phân định phụ = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

    Mục đích của các ký tự dành riêng là cung cấp một tập hợp các ký tự phân cách có thể phân biệt với các dữ liệu khác trong URI. Các URI khác nhau trong việc thay thế một ký tự dành riêng bằng octet được mã hóa phần trăm tương ứng của nó là không tương đương.

  • Nhân vật không được giám sát :A-Za-z0-9-_.~

    không đáp ứng = ALPHA / DIGIT / "-" / "." / "_" / "~"

    Các ký tự được cho phép trong URI nhưng không có mục đích dành riêng được gọi là không được giám sát.


3

Thay đổi sắp tới là dành cho tên miền tiếng Ả Rập, tiếng Ả Rập không phải là URI. Các URI quốc tế hóa được gọi là IRI và được định nghĩa trong RFC 3987 . Tuy nhiên, đã nói rằng tôi khuyên bạn không nên tự làm việc này mà chỉ dựa vào thư viện đã được thử nghiệm vì có rất nhiều lựa chọn về mã hóa / giải mã URI và những gì được coi là an toàn theo đặc tả, so với những gì an toàn khi sử dụng thực tế (trình duyệt) .


0

Nếu bạn muốn cung cấp một loại trải nghiệm đặc biệt cho người dùng, bạn có thể sử dụng pushStateđể đưa một loạt các ký tự vào url của trình duyệt:

nhập mô tả hình ảnh ở đây

var u="";var tt=168;
for(var i=0; i< 250;i++){
 var x = i+250*tt;
console.log(x);
 var c = String.fromCharCode(x);
 u+=c; 
}
history.pushState({},"",250*tt+u);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.