Karakter diizinkan dalam URL

191

Adakah yang tahu daftar karakter lengkap yang dapat digunakan dalam GET tanpa dikodekan? Saat ini saya menggunakan AZ az dan 0-9 ... tapi saya mencari tahu daftar lengkapnya.

Saya juga tertarik jika ada spesifikasi yang dirilis untuk penambahan bahasa Cina, bahasa Arab (yang jelas akan berdampak besar pada pertanyaan saya)

Menandai
sumber
5
Karakter yang diizinkan dalam URI dapat dipesan !*'();:@&=+$,/?#[]atau tidak dilindungi A-Za-z0-9_.~-(atau karakter persen %sebagai bagian dari pengkodean persen)
Mikl
1
Di MySQL saya menggunakan ini REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'untuk menemukan string URL dengan karakter buruk. Mungkin itu berguna untuk orang lain juga.
Mikl
@ Mik: Hal itu hampir tidak terlihat seperti ekspresi biasa.
Jens Mander

Jawaban:

182

Dari spesifikasi RFC 1738 :

Dengan demikian, hanya alfanumerik, karakter khusus " $-_.+!*'(),", dan karakter khusus yang digunakan untuk tujuan khusus mereka yang dapat digunakan tanpa kode di dalam URL.

EDIT: Seperti yang ditunjukkan oleh @Jukka K. Korpela, RFC ini diperbarui oleh RFC 3986 . Ini telah memperluas dan mengklarifikasi karakter yang valid untuk host, sayangnya itu tidak mudah disalin dan ditempelkan, tetapi saya akan melakukan yang terbaik.

Dalam urutan pertama yang cocok:

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
Myles
sumber
5
@Tim slash adalah karakter yang dicadangkan, oleh karena itu, jika sedang digunakan untuk tujuan yang dicadangkan (delineating paths, delineation protokol ...), maka tidak perlu melarikan diri. Kalau tidak, itu akan terjadi.
Myles
4
Aturan sintaksis umum RFC 1738 sudah usang pada tahun 1998.
Jukka K. Korpela 8'13
3
@Myles, STD 66 (= RFC 3986) disebutkan dalam jawaban lain. Apakah isi jawaban itu benar atau tidak, adalah masalah yang berbeda; Saya tidak berpikir salah satu jawaban dengan benar menggambarkan daftar lengkap.
Jukka K. Korpela
4
Dan Anda dapat menambahkan daftar A-Za-z0-9_.-~karakter yang tidak dilindungi dan dilindungi undang-undang di awal jawaban ini. !*'();:@&=+$,/?#[]Ini dapat menghemat waktu untuk orang
Mikl
2
@ basZero Maaf Anda merasa ini membingungkan, tetapi jawaban lengkapnya tidak sederhana. Jawaban atas pertanyaan Anda adalah tidak, karena ini adalah karakter khusus seperti yang dinyatakan oleh:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles
42

Karakter yang diizinkan dalam URI dapat dipesan atau tidak dipesan (atau karakter persen sebagai bagian dari penyandian-persen)

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

mengatakan ini adalah RFC 3986 karakter tanpa syarat (bagian 2.3) serta karakter yang dipesan (bagian 2.2) jika mereka perlu mempertahankan makna khusus mereka. Dan juga karakter persen sebagai bagian dari pengkodean persen.

Amber
sumber
7
Meskipun tautan ini dapat menjawab pertanyaan, lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini dan memberikan tautan untuk referensi. Jawaban hanya tautan dapat menjadi tidak valid jika halaman tertaut berubah.
jaestevan
@jaestevan Kutipan dari dokumen yang ditautkan:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl
26

Daftar lengkap dari 66 karakter tanpa pagu harga ada di RFC3986, di sini: http://tools.ietf.org/html/rfc3986#section-2.3

Ini adalah karakter apa pun dalam rangkaian regex berikut:

[A-Za-z0-9_.\-~]
slacy
sumber
2
Anda dapat menggunakan itu juga dipesan.
Qwerty
RFC1738 usang terdaftar {}^\~dan backticktidak aman. Dan RFC3986 daftar \ sebagai tidak aman karena sistem file. Ini artinya {}^bisa digunakan juga.
mgutt
Jadi, jika Anda mencoba, katakanlah, menemukan akhir url di dalam string (yang saya), akan lebih baik untuk pergi dengan standar usang dalam jawaban yang diterima ... Jika Anda memvalidasi url, Anda harus gunakan serangkaian karakter pada jawaban ini .
ashleedawg
Hati-hati, Anda telah menulis ini sebagai kelas karakter ekspresi reguler. Pastikan untuk melarikan diri -atau meletakkannya di awal atau akhir kelas karakter, karena [.-~]sebenarnya berisi semua karakter ASCII dari 46 hingga 126.
kwl
19

Saya mengujinya dengan meminta situs web saya (apache) dengan semua karakter yang tersedia di keyboard jerman saya sebagai parameter URL:

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

Ini tidak disandikan:

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

Tidak disandikan setelah urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Tidak disandikan setelah rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Catatan: Sebelum PHP 5.3.0 rawurlencode()disandikan ~karena RFC 1738 . Tapi ini digantikan oleh RFC 3986 sehingga aman digunakan, sekarang. Tapi saya tidak mengerti mengapa misalnya {}dikodekan melalui rawurlencode()karena mereka tidak disebutkan dalam RFC 3986.

Tes tambahan yang saya lakukan adalah tentang penautan otomatis dalam teks surat. Saya menguji Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de dan yahoo.de dan mereka sepenuhnya menautkan URL yang berisi karakter ini:

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

Tentu saja ?itu ditautkan juga, tetapi hanya jika digunakan sekali.

Beberapa orang sekarang menyarankan untuk menggunakan hanya rawurlencode()karakter, tetapi apakah Anda pernah mendengar bahwa seseorang memiliki masalah untuk membuka situs web ini?

Asterisk
http://wayback.archive.org/web/*/http://google.com

Colon
https://en.wikipedia.org/wiki/Wikipedia:About

Plus
https://plus.google.com/+google

Pada tanda, tanda titik dua, tanda koma dan tanda seru
https: //www.google.com/maps/place/USA/@36.2218457, ...

Karena itu karakter ini harus dapat digunakan tanpa kode tanpa masalah. Tentu saja Anda tidak boleh menggunakan &;karena urutan pengkodean seperti &amp;. Alasan yang sama berlaku karena %digunakan untuk menyandikan karakter secara umum. Dan =saat memberikan nilai ke nama parameter.

Akhirnya saya akan mengatakan tidak apa-apa untuk menggunakan ini tanpa kode:

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

Tetapi jika Anda mengharapkan URL yang dibuat secara acak sebaiknya tidak Anda gunakan .!, karena itu menandai akhir kalimat dan beberapa aplikasi email tidak akan otomatis menautkan karakter terakhir dari url. Contoh:

Visit http://example.com/foo=bar! !
mgutt
sumber
Pendekatan praktis - pekerjaan bagus. Sedang mencari daftar terakhir Anda - +pertanda terutama :-D
Oliver
12

Dari sini

Dengan demikian, hanya alfanumerik, karakter khusus $-_.+!*'(), dan karakter khusus yang digunakan untuk tujuan khusus mereka yang dapat digunakan tanpa kode di dalam URL.

AdaTheDev
sumber
6

RFC3986 mendefinisikan dua set karakter yang dapat Anda gunakan dalam URI:

  • Karakter yang Dicadangkan ::/?#[]@!$&'()*+,;=

    reserved = gen-delims / sub-delims

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

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

    Tujuan dari karakter yang dipesan adalah untuk menyediakan satu set karakter pembatas yang dapat dibedakan dari data lain dalam URI. URI yang berbeda dalam penggantian karakter yang dipesan dengan oktet berkode persen yang sesuai tidak setara.

  • Karakter Tanpa Cadangan :A-Za-z0-9-_.~

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

    Karakter yang diizinkan dalam URI tetapi tidak memiliki tujuan khusus disebut tidak dapat diterima.

Cyker
sumber
3

Perubahan yang akan datang adalah untuk nama domain cina, arab bukan URI. URI yang terinternasionalisasi disebut IRI dan didefinisikan dalam RFC 3987 . Namun, setelah mengatakan bahwa saya akan merekomendasikan untuk tidak melakukan ini sendiri tetapi mengandalkan pustaka yang sudah teruji, karena ada banyak pilihan pengkodean / decoding URI dan apa yang dianggap aman berdasarkan spesifikasi, versus apa yang aman dengan penggunaan aktual (browser) .

dajobe
sumber
0

Jika Anda ingin memberikan pengalaman khusus kepada pengguna yang dapat Anda gunakan pushStateuntuk menghadirkan beragam karakter ke url browser:

masukkan deskripsi gambar di sini

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);
Suram
sumber