อักขระที่อนุญาตใน URL


191

ไม่มีใครรู้รายชื่อตัวละครทั้งหมดที่สามารถใช้ได้ภายใน GET โดยไม่ต้องเข้ารหัส? ในขณะนี้ฉันกำลังใช้ AZ az และ 0-9 ... แต่ฉันกำลังค้นหารายชื่อทั้งหมด

ฉันสนใจด้วยหากมีข้อกำหนดที่วางจำหน่ายสำหรับการเพิ่มขึ้นมาของภาษาจีน, URL ของภาษาอาหรับ (ตามที่เห็นได้ชัดว่าจะมีผลกระทบอย่างมากต่อคำถามของฉัน)


5
ตัวละครที่ได้รับอนุญาตใน URI สงวนไว้อย่างใดอย่างหนึ่ง!*'();:@&=+$,/?#[]หรือตรงไปตรงมาA-Za-z0-9_.~-(หรือตัวละครที่ร้อยละ%เป็นส่วนหนึ่งของการเข้ารหัสเปอร์เซ็นต์)
Mikl

1
ใน MySQL ฉันใช้สิ่งนี้REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'เพื่อค้นหาสตริง URL ที่มีอักขระไม่ดี อาจเป็นประโยชน์กับคนอื่นด้วย
Mikl

@ Mikl: สิ่งที่ดูเหมือนจะไม่แสดงออกปกติ
Jens Mander

คำตอบ:


182

จากข้อกำหนดRFC 1738 :

ดังนั้นจึงมีเพียงตัวอักษรและตัวเลขอักขระพิเศษ " $-_.+!*'()," และอักขระที่สงวนไว้ซึ่งใช้เพื่อวัตถุประสงค์ที่สงวนไว้เท่านั้นที่สามารถใช้รหัสแบบไม่เข้ารหัสภายใน URL

แก้ไข: ในฐานะที่เป็น @Jukka เค Korpela อย่างถูกต้องชี้ให้เห็น RFC นี้ได้รับการปรับปรุงโดยRFC 3986 สิ่งนี้ได้ขยายและชี้แจงอักขระที่ใช้ได้สำหรับโฮสต์โชคไม่ดีที่มันไม่ได้คัดลอกและวาง แต่ฉันจะทำให้ดีที่สุด

ในการจับคู่แรก:

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
@Tim slash เป็นอักขระที่สงวนไว้ดังนั้นหากมีการใช้เพื่อวัตถุประสงค์ที่สงวนไว้ (การกำหนดพา ธ การกำหนดโพรโทคอล ... ) ดังนั้นจึงไม่จำเป็นต้องหลบหนี มิฉะนั้นจะทำ
Myles

4
กฎไวยากรณ์ทั่วไปของ RFC 1738 ถูกเลิกใช้แล้วในปี 1998
Jukka K. Korpela

3
@ Myles, STD 66 (= RFC 3986) ถูกกล่าวถึงในคำตอบอื่น ๆ เนื้อหาของคำตอบนั้นถูกต้องหรือไม่นั้นเป็นปัญหาที่ต่างออกไป ฉันไม่คิดว่าคำตอบใด ๆ จะอธิบายรายการทั้งหมดได้อย่างถูกต้อง
Jukka K. Korpela

4
และคุณสามารถเพิ่มรายการA-Za-z0-9_.-~อักขระที่ไม่ได้จองและสำรองไว้ในตอนต้นของคำตอบนี้ !*'();:@&=+$,/?#[]มันสามารถประหยัดเวลาสำหรับผู้คน
Mikl

2
@basZero ฉันขอโทษที่คุณพบว่ามันสับสน แต่คำตอบเต็มนั้นไม่ง่ายเลย คำตอบสำหรับคำถามของคุณคือไม่เนื่องจากเป็นอักขระที่สงวนไว้ตามที่ระบุไว้โดย:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles

42

อักขระที่ได้รับอนุญาตใน URI นั้นสงวนไว้หรือไม่ได้รับการจอง (หรืออักขระร้อยละเป็นส่วนหนึ่งของการเข้ารหัสแบบร้อยละ)

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

กล่าวว่าสิ่งเหล่านี้คือRFC 3986 อักขระที่ไม่ได้จอง (วินาที 2.3) รวมถึงอักขระที่สงวนไว้ (วินาที 2.2) หากพวกเขาต้องการรักษาความหมายพิเศษของพวกเขา และยังมีอักขระเปอร์เซ็นต์เป็นส่วนหนึ่งของการเข้ารหัสเปอร์เซ็นต์


7
แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าเว็บที่เชื่อมโยงมีการเปลี่ยนแปลง
jaestevan

@jaestevan การอ้างอิงจากเอกสารที่เชื่อมโยง:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl

26

รายการทั้งหมดของ 66 ตัวอักษรที่ไม่ได้จองอยู่ใน RFC3986 ที่นี่: http://tools.ietf.org/html/rfc3986#section-2.3

นี่คืออักขระใด ๆ ในชุด regex ต่อไปนี้:

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

2
คุณสามารถใช้สิ่งที่สงวนไว้เช่นกัน
Qwerty

RFC1738 ที่ล้าสมัยอยู่ในรายการ{}^\~และbacktickไม่ปลอดภัย และ RFC3986 แสดงรายการ \ ไม่ปลอดภัยเนื่องจากระบบไฟล์ วิธีนี้{}^สามารถใช้ได้เช่นกัน
mgutt

ดังนั้นหากคุณพยายามพูดหาจุดสิ้นสุดของurl ภายในสตริง (ซึ่งฉัน) มันจะเป็นการดีที่สุดที่จะไปตามมาตรฐานที่ล้าสมัยในคำตอบที่ยอมรับ ... หากคุณตรวจสอบความถูกต้องของ urlคุณควร ใช้ชุดของตัวละครในเรื่องนี้คำตอบ
ashleedawg

ระวังคุณเขียนสิ่งนี้เป็นคลาสอักขระนิพจน์ปกติ ตรวจสอบให้แน่ใจที่จะหลบหนี-หรือวางไว้ที่จุดเริ่มต้นหรือจุดสิ้นสุดของตัวละครคลาสเพราะ[.-~]จริงมีอักขระ ASCII ทั้งหมดจาก 46 126
KWL

19

ฉันทดสอบโดยขอเว็บไซต์ (apache) พร้อมตัวอักษรทั้งหมดที่มีอยู่บนแป้นพิมพ์ภาษาเยอรมันเป็นพารามิเตอร์ URL:

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

สิ่งเหล่านี้ไม่ได้เข้ารหัส:

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

ไม่ได้เข้ารหัสหลังจากurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

ไม่ได้เข้ารหัสหลังจากrawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

หมายเหตุ: ก่อน PHP 5.3.0 rawurlencode()เข้ารหัส~เพราะRFC 1738 แต่นี่ถูกแทนที่ด้วยRFC 3986ดังนั้นมันจึงปลอดภัยที่จะใช้ตอนนี้ แต่ฉันไม่เข้าใจว่าทำไม{}มีการเข้ารหัสตัวอย่างเช่นrawurlencode()เพราะพวกเขาไม่ได้กล่าวถึงใน RFC 3986

การทดสอบเพิ่มเติมที่ฉันทำคือเกี่ยวกับการลิงก์อัตโนมัติในข้อความอีเมล ฉันทดสอบ Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de และ yahoo.de และพวกเขาเชื่อมโยง URL ทั้งหมดที่มีตัวอักษรเหล่านี้:

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

แน่นอนว่ามีการ?เชื่อมโยงเช่นกัน แต่ถ้าใช้ครั้งเดียวเท่านั้น

บางคนอาจแนะนำให้ใช้เฉพาะตัวrawurlencode()อักษร แต่คุณเคยได้ยินว่ามีคนมีปัญหาในการเปิดเว็บไซต์เหล่านี้หรือไม่

ดอกจัน
http://wayback.archive.org/web/*/http://google.com

โคลอน
https://en.wikipedia.org/wiki/Wikipedia:About

พลัส
https://plus.google.com/+google

ที่ลงชื่อเครื่องหมายลำไส้ใหญ่เครื่องหมายจุลภาคและเครื่องหมายอัศเจรีย์
https: //www.google.com/maps/place/USA/@36.2218457, ...

เนื่องจากตัวอักษรเหล่านี้ควรใช้งานได้โดยไม่มีการเข้ารหัสโดยไม่มีปัญหา แน่นอนคุณไม่ควรใช้เพราะเข้ารหัสลำดับเช่น&; &amp;เหตุผลเดียวกันนี้ใช้ได้สำหรับ%การเข้ารหัสทั่วไป และ=ในขณะที่มันกำหนดค่าให้กับชื่อพารามิเตอร์

ในที่สุดฉันจะบอกว่ามันโอเคที่จะใช้การเข้ารหัสเหล่านี้:

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

แต่ถ้าคุณคาดหวังว่า URL ที่สร้างขึ้นแบบสุ่มคุณไม่ควรใช้.!เพราะสิ่งเหล่านั้นทำเครื่องหมายจุดสิ้นสุดของประโยคและแอปอีเมลบางตัวจะไม่เชื่อมโยงอักขระตัวสุดท้ายของ URL โดยอัตโนมัติ ตัวอย่าง:

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

วิธีการปฏิบัติ - งานที่ดี กำลังมองหารายชื่อสุดท้ายของคุณ - +เครื่องหมายโดยเฉพาะ :-D
Oliver

12

จากที่นี่

ดังนั้นจึงมีเพียงตัวอักษรและตัวเลขอักขระพิเศษ$-_.+!*'(), และอักขระที่สงวนไว้ซึ่งใช้เพื่อวัตถุประสงค์ในการจองเท่านั้นจึงอาจไม่ได้รับการเข้ารหัสภายใน URL



6

RFC3986กำหนดอักขระสองชุดที่คุณสามารถใช้ใน URI:

  • ตัวละครที่จองไว้ ::/?#[]@!$&'()*+,;=

    สงวน = gen-delims / sub-delims

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

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

    วัตถุประสงค์ของตัวละครที่สงวนไว้คือการให้ชุดของตัวละครที่คั่นที่แตกต่างจากข้อมูลอื่น ๆ ภายใน URI URIs ที่แตกต่างกันในการแทนที่อักขระที่สงวนไว้ด้วย octet ที่เข้ารหัสร้อยละที่สอดคล้องกันจะไม่เทียบเท่า

  • ตัวละครที่ไม่ได้จอง :A-Za-z0-9-_.~

    ไม่ได้จอง = ALPHA / DIGIT / "-" / "." / "_" / "~"

    อักขระที่ได้รับอนุญาตใน URI แต่ไม่มีวัตถุประสงค์ที่สงวนไว้จะถูกเรียกว่า unreserved


3

การเปลี่ยนแปลงที่จะเกิดขึ้นสำหรับจีนชื่อโดเมนภาษาอาหรับไม่ใช่ URIs URI ของสากลที่เรียกว่าไอริสและมีการกำหนดไว้ในRFC 3987 อย่างไรก็ตามต้องบอกว่าฉันไม่แนะนำให้ทำแบบนี้ด้วยตัวคุณเอง แต่พึ่งพาไลบรารีที่มีอยู่และทดสอบแล้วเนื่องจากมีตัวเลือกมากมายสำหรับการเข้ารหัส / ถอดรหัส URI และสิ่งที่ถือว่าปลอดภัยโดยสเปคกับสิ่งที่ปลอดภัยจากการใช้งานจริง (เบราว์เซอร์) .


0

หากคุณต้องการมอบประสบการณ์พิเศษให้กับผู้ใช้คุณสามารถใช้pushStateเพื่อนำอักขระที่หลากหลายไปยัง URL ของเบราว์เซอร์:

ป้อนคำอธิบายรูปภาพที่นี่

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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.