อักขระใดทำให้ URL ไม่ถูกต้อง
URL ที่ถูกต้องเหล่านี้หรือไม่
example.com/file[/].html
http://example.com/file[/].html
อักขระใดทำให้ URL ไม่ถูกต้อง
URL ที่ถูกต้องเหล่านี้หรือไม่
example.com/file[/].html
http://example.com/file[/].html
คำตอบ:
โดยทั่วไป URI ตามที่กำหนดโดยRFC 3986 (ดูหัวข้อที่ 2: ตัวอักษร ) อาจมีอักขระ 84 ตัวต่อไปนี้:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
โปรดทราบว่ารายการนี้ไม่ได้ระบุว่าอักขระเหล่านี้อาจเกิดขึ้นที่ใดใน URI
อักขระอื่น ๆ จำเป็นต้องเข้ารหัสด้วยการเข้ารหัสเปอร์เซ็นต์ ( %
hh
) แต่ละส่วนของ URI มีข้อ จำกัด เพิ่มเติมเกี่ยวกับสิ่งที่ตัวละครจะต้องแสดงด้วยคำที่เข้ารหัสร้อยละ
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
มีอะไรอีกที่คุณคิดว่ามันควรจะได้รับการยอมรับ? (เพียงเพื่อให้ชัดเจน regex นั้นจะตรวจสอบว่าสตริงมีอักขระ URL ที่ถูกต้องเท่านั้นไม่ใช่ถ้าสตริงนั้นประกอบด้วย URL ที่มีรูปแบบถูกต้อง)
หากต้องการเพิ่มความกระจ่างและตอบคำถามโดยตรงด้านบนมีหลายคลาสของอักขระที่ทำให้เกิดปัญหากับ URL และ URIs
มีอักขระบางตัวที่ไม่ได้รับอนุญาตและไม่ควรปรากฏใน URL / URI, อักขระที่สงวนไว้ (อธิบายด้านล่าง) และอักขระอื่น ๆ ที่อาจทำให้เกิดปัญหาในบางกรณี แต่มีการทำเครื่องหมายว่า "ไม่ฉลาด" หรือ "ไม่ปลอดภัย" คำอธิบายว่าทำไมอักขระถูก จำกัด อย่างชัดเจนสะกดในRFC-1738 (URL) และRFC-2396 (URIs) หมายเหตุRFC-3986 ที่ใหม่กว่า(อัปเดตเป็น RFC-1738) กำหนดโครงสร้างของอักขระที่ได้รับอนุญาตในบริบทที่กำหนด แต่ข้อมูลจำเพาะรุ่นเก่ามีคำอธิบายที่ง่ายกว่าและทั่วไปกว่าซึ่งอักขระไม่ได้รับอนุญาตด้วยกฎต่อไปนี้
ไม่รวมอักขระ US-ASCII ที่ไม่อนุญาตภายในไวยากรณ์ URI:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
ไม่รวมอักขระ "#" เนื่องจากถูกใช้เพื่อคั่น URI จากตัวระบุส่วน อักขระเปอร์เซ็นต์ "%" ถูกแยกออกเนื่องจากใช้สำหรับการเข้ารหัสอักขระที่ใช้ Escape กล่าวอีกนัยหนึ่ง "#" และ "%" เป็นอักขระที่สงวนไว้ซึ่งต้องใช้ในบริบทเฉพาะ
อนุญาตรายการที่ไม่ฉลาด แต่อาจทำให้เกิดปัญหา:
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
ข้อ จำกัด บางตัวอักขระสำหรับ URIs / URL ขึ้นอยู่กับภาษาการเขียนโปรแกรม ตัวอย่างเช่น '|' อักขระ (0x7C) ถึงแม้ว่าจะทำเครื่องหมายว่า "ไม่ฉลาด" ในข้อมูลจำเพาะ URI จะโยนURISyntaxExceptionในตัวสร้าง Java java.net.URIดังนั้น URL เช่นhttp://api.google.com/q?exp=a|b
นี้จะไม่ได้รับอนุญาตและจะต้องเข้ารหัสแทนเสมือนhttp://api.google.com/q?exp=a%7Cb
ใช้ Java กับอินสแตนซ์วัตถุ URI
?
นั้นใช้ได้ดีในส่วนของการสืบค้น แต่ไม่สามารถทำได้ก่อนหน้านี้และฉันไม่คิดว่าจะ@
เป็นของรายการใด ๆ เหล่านี้ โอ้และแทนที่จะ%25
เป็นสายสุดท้ายคุณหมายถึง%7C
อะไรเหรอ?
คำตอบที่มีอยู่ส่วนใหญ่ที่นี่ทำไม่ได้เพราะพวกเขาไม่สนใจการใช้ที่อยู่ในโลกแห่งความเป็นจริงเช่น:
ก่อนการพูดนอกเรื่องเป็นคำศัพท์ ที่อยู่เหล่านี้คืออะไร? เป็น URL ที่ถูกต้องหรือไม่
คำตอบคือ "ไม่" ในอดีต ตามRFC 3986จากปี 2005 ที่อยู่ดังกล่าวไม่ใช่ URIs (และไม่ใช่ URL เนื่องจาก URL เป็นประเภทของ URIs ) ตามคำศัพท์ของมาตรฐาน IETF ปี 2548 เราควรเรียกพวกเขาว่า IRIs (Internationalized Resource Identifiers) อย่างถูกต้องตามที่กำหนดไว้ในRFC 3987ซึ่งในทางเทคนิคไม่ใช่ URIs แต่สามารถแปลงเป็น URIs ได้ง่ายๆโดยการเข้ารหัสเปอร์เซ็นต์อักขระที่ไม่ใช่ ASCII ทั้งหมดใน IRI .
ตามข้อมูลจำเพาะที่ทันสมัยคำตอบคือ "ใช่" WHATWG Living มาตรฐานเพียง classifies ทุกอย่างที่จะไปก่อนหน้านี้จะเรียกว่า "ยูริ" หรือ "ไอริส" เป็น "URL ที่" นี้สอดคล้องกับคำศัพท์ specced กับคนวิธีปกติที่ยังไม่ได้อ่านการใช้สเปคคำว่า "URL" ซึ่งเป็นหนึ่งในสเป็คของเป้าหมาย
ตามความหมายที่ใหม่กว่านี้ของ "URL" อนุญาตให้ใช้อักขระใดบ้าง ในหลาย ๆ ส่วนของ URL เช่นสตริงการสืบค้นและพา ธ เราได้รับอนุญาตให้ใช้"หน่วย URL"โดยพลการซึ่ง ได้แก่
จุดรหัส URLและไบต์ร้อยละเข้ารหัส
"คะแนนรหัส URL" คืออะไร
จุดรหัส URL ที่เป็นตัวเลขและตัวอักษร ASCII, U + 0021 (!), U + 0024 ($) U + 0026 (&), U + 0027 ( '), U + 0028 วงเล็บ, U + 0029 ขวาวงเล็บ U + 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" หากเป็นส่วนหนึ่งของลำดับการเข้ารหัสแบบร้อยละ)
ที่เดียวที่ฉันสามารถเห็นจุดที่ spec อนุญาตให้ใช้อักขระใด ๆ ที่ไม่ได้อยู่ในชุดนี้อยู่ในโฮสต์ที่ที่อยู่ IPv6 อยู่ในนั้น[
และ]
ตัวอักษร ทุกที่ใน URL สามารถใช้หน่วย URL หรือชุดอักขระที่ จำกัด ยิ่งขึ้น
เพื่อประโยชน์ของประวัติศาสตร์และเนื่องจากมันไม่ได้รับการสำรวจอย่างเต็มที่ในคำตอบที่นี่เราจะตรวจสอบภายใต้สเป็คคู่เก่า
ก่อนอื่นเรามี RFC 3986 ตัวละครสำรองสองประเภท :
:/?#[]@
ซึ่งเป็นส่วนหนึ่งของไวยากรณ์ทั่วไปสำหรับ URI ที่กำหนดใน RFC 3986!$&'()*+,;=
ซึ่งไม่ได้เป็นส่วนหนึ่งของไวยากรณ์ทั่วไปของ RFC แต่สงวนไว้สำหรับใช้เป็นองค์ประกอบทางไวยากรณ์ของรูปแบบ URI เฉพาะ ยกตัวอย่างเช่นอัฒภาคและจุลภาคถูกนำมาใช้เป็นส่วนหนึ่งของไวยากรณ์ของURI ของข้อมูลและ&
และ=
ถูกนำมาใช้เป็นส่วนหนึ่งของที่แพร่หลาย?foo=bar&qux=baz
ในรูปแบบสตริงแบบสอบถาม (ซึ่งไม่ได้ระบุโดย RFC 3986)อักขระที่สงวนไว้ข้างต้นใด ๆ สามารถใช้งานได้อย่างถูกกฎหมายใน URI โดยไม่ต้องเข้ารหัสไม่ว่าจะเป็นการให้บริการตามวัตถุประสงค์ของประโยคหรือเพียงแค่ตัวอักษรตามตัวอักษรในข้อมูลในบางสถานที่ที่การใช้งานดังกล่าวไม่สามารถตีความได้ผิด (ตัวอย่างเช่นแม้ว่าจะ/
มีความหมายทางไวยากรณ์ใน URL คุณสามารถใช้มันไม่ได้เข้ารหัสในสตริงการสืบค้นเพราะมันไม่มีความหมายในสตริงการสืบค้น)
RFC 3986 ยังระบุอักขระที่ไม่ได้จองไว้บางตัวซึ่งสามารถใช้เพื่อแสดงข้อมูลโดยไม่ต้องเข้ารหัส:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
ในที่สุด%
ตัวละครที่ได้รับอนุญาตสำหรับการเข้ารหัสร้อยละ
ที่เหลือเพียงอักขระ ASCII ต่อไปนี้ที่ถูกห้ามไม่ให้ปรากฏใน URL:
"<>\^`{|}
อักขระอื่น ๆ จาก ASCII สามารถมีคุณสมบัติตามกฎหมายใน URL
จากนั้น RFC 3987 จะขยายชุดของอักขระที่ไม่ได้สำรองไว้ด้วยช่วงอักขระ unicode ต่อไปนี้:
%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
เหล่านี้เลือกที่ตึกจากสเปคเก่าดูเหมือนแปลกประหลาดและพลได้รับล่าสุด Unicode นิยามบล็อก ; อาจเป็นเพราะมีการเพิ่มบล็อกในช่วงทศวรรษนับตั้งแต่มีการเขียน RFC 3987
ในที่สุดอาจเป็นเรื่องน่าสังเกตว่าการรู้ว่าอักขระใดที่สามารถปรากฏใน URL อย่างถูกกฎหมายนั้นไม่เพียงพอที่จะรับรู้ว่าสตริงที่กำหนดเป็น URL ที่ถูกกฎหมายหรือไม่เนื่องจากอักขระบางตัวนั้นถูกต้องตามกฎหมายในบางส่วนของ URL ตัวอย่างเช่นตัวละครที่สงวนไว้[
และ]
ถูกกฎหมายเป็นส่วนหนึ่งของโฮสต์ตัวอักษร IPv6 ใน URL เช่นhttp: // [1080 :: 8: 800: 200C: 417A] / fooแต่ไม่ถูกกฎหมายในบริบทอื่นดังนั้น ตัวอย่างของ OP http://example.com/file[/].html
นั้นผิดกฎหมาย
ในคำถามเสริมที่คุณถามว่าwww.example.com/file[/].html
เป็น URL ที่ถูกต้องหรือไม่
URL นั้นไม่ถูกต้องเนื่องจาก URL เป็นประเภทของ URI และ URI ที่ถูกต้องจะต้องมีรูปแบบเช่นhttp:
(ดูRFC 3986 )
หากคุณต้องการถามว่าhttp://www.example.com/file[/].html
เป็น URL ที่ถูกต้องหรือไม่คำตอบนั้นยังคงไม่เป็นเพราะอักขระวงเล็บเหลี่ยมไม่ถูกต้อง
อักขระวงเล็บเหลี่ยมถูกสงวนไว้สำหรับ URL ในรูปแบบนี้: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(เช่นตัวอักษร IPv6 แทนที่จะเป็นชื่อโฮสต์)
เป็นมูลค่าการอ่าน RFC 3986 อย่างรอบคอบหากคุณต้องการเข้าใจปัญหาอย่างเต็มที่
[
และ]
ไม่ได้ URI ที่ถูกต้องสำหรับเกือบ parsers ฉันได้เห็น สิ่งนี้ทำให้ฉันเมาในโลกแห่งความเป็นจริง: stackoverflow.com/questions/11038967/…
Unwise
สำหรับ URIs อย่างจริงจังและยังใช้ได้กับ URL ของไลบรารี Unwise
นั่นคือมีธงที่จะไม่สนใจไม่ ฉันจะต้องตรวจสอบสิ่งที่รัส lang (เพราะมันถูกสร้างขึ้นสำหรับเบราว์เซอร์ฉันอยากรู้ว่ามันทำอะไร) สำหรับ URL แม้ว่าเบราว์เซอร์ส่วนใหญ่จะผ่าน "[", "]" ด้วยเช่นกัน ดังนั้นในทางทฤษฎีเหมือนกับที่ฉันพูดกับ C / C ++ พวกเขาเป็น sub / super แต่ความจริงก็ไม่ได้เป็นเช่นนั้น มันขึ้นอยู่กับการตีความของ spec และความหมายของ super / subset
ทั้งหมดที่ถูกต้องตัวอักษรที่สามารถนำมาใช้ใน URI (กURL ที่เป็นชนิดของURI ) ที่กำหนดไว้ในRFC 3986
อักขระอื่น ๆ ทั้งหมดสามารถใช้ใน URL โดยมีเงื่อนไขว่าเป็น "URL ที่เข้ารหัส" ก่อน สิ่งนี้เกี่ยวข้องกับการเปลี่ยนอักขระที่ไม่ถูกต้องสำหรับ "รหัส" เฉพาะ (โดยปกติจะอยู่ในรูปแบบของสัญลักษณ์เปอร์เซ็นต์ (%) ตามด้วยตัวเลขฐานสิบหก)
ลิงค์นี้อ้างอิงการเข้ารหัส HTML URLมีรายการการเข้ารหัสสำหรับอักขระที่ไม่ถูกต้อง
ช่วงอักขระ Unicode หลายช่วงเป็น HTML5 ที่ถูกต้องแม้ว่าอาจยังไม่ควรใช้ก็ตาม
เช่นhref
เอกสารพูดว่าhttp://www.w3.org/TR/html5/links.html#attr-hyperlink-href :
แอตทริบิวต์ href ในองค์ประกอบ a และพื้นที่ต้องมีค่าที่เป็น 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 + 10,000 ถึง U + 1FFFD, U + 20,000 ถึง U + 2FFFD, U + 30000 ถึง U + 3FFFD, U + 40000 ถึง U + 4FFFD, U + 500FFFD, U +60000 ถึง U + 6FFFD, U + 70000 ถึง U + 7FFFD, U + 80000 ถึง U + 8FFFD, U + 90000 ถึง U + 9FFFD, U + A0000 ถึง U + AFFFD, U + BFFFD, U + C0000 ถึง U + CFFFD, U + D0000 ถึง U + DFFFD, U + E1000 ถึง U + EFFFD, U + F0000 ถึง U + FFFFD, U + 100000 ถึง U + 10FFFD
คำว่า "URL code points" จะถูกใช้ในคำสั่ง:
หาก c ไม่ใช่จุดรหัส URL และไม่ใช่ "%" แสดงว่าเกิดข้อผิดพลาดในการแยกวิเคราะห์
ในส่วนต่างๆของอัลกอริทึมการแยกวิเคราะห์รวมถึงสคีมาผู้มีอำนาจเส้นทางสัมพัทธ์การสืบค้นและการแยกส่วน: โดยทั่วไปแล้ว URL ทั้งหมด
นอกจากนี้ validator http://validator.w3.org/จะส่งผ่าน URL ที่ต้องการ"你好"
และจะไม่ส่งผ่าน URL ที่มีอักขระเช่นช่องว่าง"a b"
แน่นอนตามที่ Stephen C กล่าวไว้มันไม่ได้เป็นเพียงแค่ตัวละคร แต่เกี่ยวกับบริบท: คุณต้องเข้าใจอัลกอริทึมทั้งหมด แต่เนื่องจาก class "URL code points" ถูกใช้ในประเด็นสำคัญของอัลกอริทึมมันจึงเป็นแนวคิดที่ดีว่าคุณสามารถใช้หรือไม่
ดูเพิ่มเติม: อักขระ Unicode ใน URL
ฉันต้องเลือกตัวละครเพื่อแยก URL เป็นสตริงดังนั้นฉันจึงตัดสินใจสร้างรายการอักขระที่ไม่สามารถหาได้ใน URL ด้วยตัวเอง:
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
"<>{}^|
ดังนั้นทางเลือกที่เป็นไปได้ที่จะมีขึ้นบรรทัดใหม่แท็บพื้นที่ทับขวาและ ฉันเดาว่าฉันจะไปกับพื้นที่หรือขึ้นบรรทัดใหม่ :)
ไม่ใช่คำตอบสำหรับคำถามของคุณ แต่การตรวจสอบความถูกต้องของ url นั้นเป็น pita ที่ร้ายแรงคุณน่าจะตรวจสอบความถูกต้องของชื่อโดเมนและปล่อยให้แบบสอบถามเป็นส่วนหนึ่งของ url นั่นคือประสบการณ์ของฉัน นอกจากนี้คุณยังสามารถใช้วิธีส่ง Ping URL และดูว่ามันส่งผลในการตอบสนองที่ถูกต้อง แต่อาจจะมากเกินไปสำหรับงานง่าย ๆ
นิพจน์ทั่วไปในการตรวจจับ URL มีมากมาย google it :)
ฉันกำลังใช้คำขอ http (0.9, 1.0, 1.1) และตัวอ่าน / เขียนตอบกลับ URI คำขอเป็นสถานที่ที่มีปัญหามากที่สุด
คุณไม่สามารถใช้ RFC 1738, 2396 หรือ 3986 ได้ มีไคลเอนต์ HTTP และเซิร์ฟเวอร์เก่าจำนวนมากที่อนุญาตให้ใช้อักขระได้มากขึ้น "GET URI HTTP/1.0" 200
ดังนั้นผมจึงได้ทำวิจัยอยู่บนพื้นฐานของการตีพิมพ์โดยบังเอิญบันทึกการเข้าถึงเว็บเซิร์ฟเวอร์:
ฉันพบว่าอักขระที่ไม่ได้มาตรฐานต่อไปนี้มักใช้ใน URI:
\ { } < > | ` ^ "
ตัวละครเหล่านี้ถูกอธิบายไว้ในRFC 1738เป็นที่ไม่ปลอดภัย
หากคุณต้องการเข้ากันได้กับไคลเอนต์ HTTP และเซิร์ฟเวอร์เก่าทั้งหมด - คุณต้องอนุญาตให้ใช้อักขระเหล่านี้ในคำขอ URI
ฉันมากับการแสดงออกปกติสำหรับ PHP ที่จะแปลง URL ในข้อความเพื่อยึดแท็ก (ก่อนอื่นจะแปลง URL. www ทั้งหมดเป็น http: // จากนั้นแปลง URL ทั้งหมดด้วย https?: // เป็น 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)
);