อักขระใดทำให้ URL ไม่ถูกต้อง


515

อักขระใดทำให้ URL ไม่ถูกต้อง

URL ที่ถูกต้องเหล่านี้หรือไม่

  • example.com/file[/].html
  • http://example.com/file[/].html

42
เมื่อตรวจสอบความถูกต้องคุณควร "คิดบวก" เสมอ: ถาม "สิ่งที่ถูกต้อง" ทุกอย่างไม่ถูกต้อง การทดสอบกับอักขระที่ถูกต้อง (น้อย) นั้นปลอดภัยกว่า (และง่ายกว่า!) มากกว่าตัวอักษรที่ไม่ถูกต้องที่เป็นไปได้ทั้งหมด
mfx

คำตอบ:


600

โดยทั่วไป URI ตามที่กำหนดโดยRFC 3986 (ดูหัวข้อที่ 2: ตัวอักษร ) อาจมีอักขระ 84 ตัวต่อไปนี้:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=

โปรดทราบว่ารายการนี้ไม่ได้ระบุว่าอักขระเหล่านี้อาจเกิดขึ้นที่ใดใน URI

อักขระอื่น ๆ จำเป็นต้องเข้ารหัสด้วยการเข้ารหัสเปอร์เซ็นต์ ( %hh) แต่ละส่วนของ URI มีข้อ จำกัด เพิ่มเติมเกี่ยวกับสิ่งที่ตัวละครจะต้องแสดงด้วยคำที่เข้ารหัสร้อยละ


31
(แน่นอนรายชื่อตัวละครไม่ได้ระบุว่าอยู่ใน uri ที่พวกเขาอาจเกิดขึ้นได้อย่างไร)
Eamon Nerbonne

75
นี่คือ regex ที่จะพิจารณาว่าสตริงทั้งหมดมีเฉพาะอักขระด้านบน: / ^ [! # $ & -; =? - [] _ ​​a-z ~] + $ /
Leif Wickland

43
@ techiferous ใช่ฉันลืมอนุญาตให้ใช้อักขระ "%" ที่หลบหนี มันควรจะดูเหมือนมากขึ้น: /^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/ มีอะไรอีกที่คุณคิดว่ามันควรจะได้รับการยอมรับ? (เพียงเพื่อให้ชัดเจน regex นั้นจะตรวจสอบว่าสตริงมีอักขระ URL ที่ถูกต้องเท่านั้นไม่ใช่ถ้าสตริงนั้นประกอบด้วย URL ที่มีรูปแบบถูกต้อง)
Leif Wickland

12
@Timwi RFC 3986 กล่าวว่า "octet ที่เข้ารหัสเป็นเปอร์เซ็นต์จะถูกเข้ารหัสเป็นอักขระ triplet ซึ่งประกอบด้วยอักขระเปอร์เซ็นต์"% "ตามด้วยตัวเลขฐานสิบหกสองหลักที่แสดงถึงค่าตัวเลขของ octet นั้น" นอกจากนี้ยังกล่าวว่า "เนื่องจากอักขระเปอร์เซ็นต์ ("% ") ทำหน้าที่เป็นตัวบ่งชี้สำหรับ octets ที่เข้ารหัสเปอร์เซ็นต์จะต้องเข้ารหัสเป็นเปอร์เซ็นต์"% 25 "เพื่อให้ octet นั้นใช้เป็นข้อมูลภายใน URI" ฉันอ่านว่าการบอกว่า "%" อาจปรากฏขึ้นหากมันตามด้วยเลขฐานสิบหกสองหลัก คุณอ่านมันได้อย่างไร
Leif Wickland

13
@Weeble regex ของฉันรวมตัวละครเหล่านั้นโดยใช้ช่วง ระหว่างและ ';' และระหว่าง '?' และ '[' คุณจะพบอักขระทั้งหมดที่คุณไม่เห็น
Leif Wickland

193

หากต้องการเพิ่มความกระจ่างและตอบคำถามโดยตรงด้านบนมีหลายคลาสของอักขระที่ทำให้เกิดปัญหากับ 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


2
คำตอบที่ยอดเยี่ยมและละเอียดถี่ถ้วนเพียงคนเดียวที่ตอบคำถามจริงโดยตรง ส่วนที่สงวนไว้อาจต้องการการทำงานเช่นตัวอักษร?นั้นใช้ได้ดีในส่วนของการสืบค้น แต่ไม่สามารถทำได้ก่อนหน้านี้และฉันไม่คิดว่าจะ@เป็นของรายการใด ๆ เหล่านี้ โอ้และแทนที่จะ%25เป็นสายสุดท้ายคุณหมายถึง%7Cอะไรเหรอ?
Bob Stein

1
ขอบคุณ เยี่ยมมาก:% 25 เป็นตัวพิมพ์ผิดในตัวอย่าง เพิ่มเชิงอรรถลงในคำอธิบายไวยากรณ์ "ลิขสิทธิ์" โดยตรงจาก RFC-2396
JasonM1

1
คำตอบนี้ไม่เลวแต่มีข้อผิดพลาดและข้อผิดพลาดบางอย่าง ในตอนแรกคุณสร้างตัวละครที่ไม่อนุญาตและตัวละครที่สงวนไว้ (สิ่งที่แตกต่างกันมาก) คุณสร้างความแตกต่างระหว่างตัวละคร "ไม่ฉลาด" และตัวละครที่ไม่อนุญาตอื่น ๆ (หล่นใน RFC 3986 และไม่เกี่ยวข้อง syntactically แม้ใน RFC 2396) ลิขสิทธิ์ทุกตัวอักษรเป็นรายการที่สงวนไว้"ในองค์ประกอบแบบสอบถาม"
Mark Amery

1
ขอบคุณไม่ได้หมายถึงกลุ่มที่ไม่อนุญาตและสงวนเหมือนกัน อัปเดตคำตอบ กฎ IMHO ใน RFC-2396 แม้ว่าเก่ากว่านั้นจะง่ายต่อการเข้าใจมากกว่ากฎที่อัปเดตในปี 3986 คำตอบนั้นสะท้อนให้เห็นว่าตัวละครตัวไหนที่มีปัญหาโดยทั่วไปมากกว่าบริบทที่อนุญาตหรือไม่อนุญาต
JasonM1

1
เป็นที่น่าสังเกตว่า Tomcat ในรุ่นล่าสุด (7.0.73+, 8.0.39+, 8.5.7+) ได้เริ่มปฏิเสธคำขอด้วยอักขระจากหมวดหมู่ "unwise" ที่มีข้อผิดพลาด HTTP 400: "พบอักขระไม่ถูกต้องในเป้าหมายคำขอ อักขระที่ถูกต้องจะถูกกำหนดใน RFC 7230 และ RFC 3986 "
Philip

101

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

ก่อนการพูดนอกเรื่องเป็นคำศัพท์ ที่อยู่เหล่านี้คืออะไร? เป็น 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" ซึ่งเป็นหนึ่งในสเป็คของเป้าหมาย

ตัวละครอะไรที่ได้รับอนุญาตภายใต้ WHATWG Living Standard?

ตามความหมายที่ใหม่กว่านี้ของ "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 เก่า

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

ก่อนอื่นเรามี RFC 3986 ตัวละครสำรองสองประเภท :

  • :/?#[]@ซึ่งเป็นส่วนหนึ่งของไวยากรณ์ทั่วไปสำหรับ URI ที่กำหนดใน RFC 3986
  • !$&'()*+,;=ซึ่งไม่ได้เป็นส่วนหนึ่งของไวยากรณ์ทั่วไปของ RFC แต่สงวนไว้สำหรับใช้เป็นองค์ประกอบทางไวยากรณ์ของรูปแบบ URI เฉพาะ ยกตัวอย่างเช่นอัฒภาคและจุลภาคถูกนำมาใช้เป็นส่วนหนึ่งของไวยากรณ์ของURI ของข้อมูลและ&และ=ถูกนำมาใช้เป็นส่วนหนึ่งของที่แพร่หลาย?foo=bar&qux=bazในรูปแบบสตริงแบบสอบถาม (ซึ่งไม่ได้ระบุโดย RFC 3986)

อักขระที่สงวนไว้ข้างต้นใด ๆ สามารถใช้งานได้อย่างถูกกฎหมายใน URI โดยไม่ต้องเข้ารหัสไม่ว่าจะเป็นการให้บริการตามวัตถุประสงค์ของประโยคหรือเพียงแค่ตัวอักษรตามตัวอักษรในข้อมูลในบางสถานที่ที่การใช้งานดังกล่าวไม่สามารถตีความได้ผิด (ตัวอย่างเช่นแม้ว่าจะ/มีความหมายทางไวยากรณ์ใน URL คุณสามารถใช้มันไม่ได้เข้ารหัสในสตริงการสืบค้นเพราะมันไม่มีความหมายในสตริงการสืบค้น)

RFC 3986 ยังระบุอักขระที่ไม่ได้จองไว้บางตัวซึ่งสามารถใช้เพื่อแสดงข้อมูลโดยไม่ต้องเข้ารหัส:

  • abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~

ในที่สุด%ตัวละครที่ได้รับอนุญาตสำหรับการเข้ารหัสร้อยละ

ที่เหลือเพียงอักขระ ASCII ต่อไปนี้ที่ถูกห้ามไม่ให้ปรากฏใน URL:

  • อักขระควบคุม (ตัวอักษร 0-1F และ 7F) รวมถึงบรรทัดใหม่แท็บและการขึ้นบรรทัดใหม่
  • "<>\^`{|}

อักขระอื่น ๆ จาก 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นั้นผิดกฎหมาย


3
plusone สำหรับการอ้างอิงอย่างละเอียด (เช่น RFC)
Yan Foto

19

ในคำถามเสริมที่คุณถามว่า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 อย่างรอบคอบหากคุณต้องการเข้าใจปัญหาอย่างเต็มที่


หลังจากอ่าน RFC ฉันมีแนวโน้มที่จะเห็นด้วยกับ @Stephen C คำอธิบายเพิ่มเติมโดยละเอียด
skolima

URL ไม่ใช่ชุดย่อยของ URI [และ]ไม่ได้ URI ที่ถูกต้องสำหรับเกือบ parsers ฉันได้เห็น สิ่งนี้ทำให้ฉันเมาในโลกแห่งความเป็นจริง: stackoverflow.com/questions/11038967/…
Adam Gent

@AdamGent URL เป็นส่วนย่อยของ URI ข้อแตกต่างระหว่างพวกเขาคือพวกเขาอธิบายถึงที่ตั้งของทรัพยากร - ซึ่งเป็นความแตกต่างทางความหมายไม่ใช่แบบวากยสัมพันธ์ หากตัวแยกวิเคราะห์ที่คุณเห็นว่าติดป้ายตัวเองว่าเป็นตัวแยกวิเคราะห์ "URI" ถือว่าวงเล็บเหลี่ยมแตกต่างจากตัวแยกวิเคราะห์ว่าเป็นตัวแยกวิเคราะห์ "URL" แสดงว่าเป็นเรื่องบังเอิญที่แท้จริงไม่ใช่ความแตกต่างระหว่าง URL และ URIs
Mark Amery

@ Mark Amery มันคล้ายกับว่า C ++ เป็น superset ของ C ส่วนใหญ่ แต่ไม่เป็นความจริงทั้งหมดเพราะ (URL และ C) นั้นเก่ากว่ามากพวกเขาต้องรวมพฤติกรรมที่ไม่เข้มงวด ปัญหาคือตัวแยกวิเคราะห์ URL จะแยกวิเคราะห์สิ่งที่ไม่ถูกต้อง URI ... และฉันหมายถึงพวกเขาส่วนใหญ่ (ตรงไปตรงมาฉันเบื่อที่จะชี้เรื่องนี้ออกไปในหลายภาษา) ไม่ใช่เรื่องบังเอิญที่มันเข้ากันได้ย้อนหลัง เราสามารถตกลงกันได้ว่าข้อมูลจำเพาะ URL เก่ากว่าอย่างน้อย?
Adam Gent

@MarkAmery มาจาก Python, C #, Java และ C บางตัวที่ parsers จะใช้Unwiseสำหรับ URIs อย่างจริงจังและยังใช้ได้กับ URL ของไลบรารี Unwiseนั่นคือมีธงที่จะไม่สนใจไม่ ฉันจะต้องตรวจสอบสิ่งที่รัส lang (เพราะมันถูกสร้างขึ้นสำหรับเบราว์เซอร์ฉันอยากรู้ว่ามันทำอะไร) สำหรับ URL แม้ว่าเบราว์เซอร์ส่วนใหญ่จะผ่าน "[", "]" ด้วยเช่นกัน ดังนั้นในทางทฤษฎีเหมือนกับที่ฉันพูดกับ C / C ++ พวกเขาเป็น sub / super แต่ความจริงก็ไม่ได้เป็นเช่นนั้น มันขึ้นอยู่กับการตีความของ spec และความหมายของ super / subset
Adam Gent

12

ทั้งหมดที่ถูกต้องตัวอักษรที่สามารถนำมาใช้ใน URI (กURL ที่เป็นชนิดของURI ) ที่กำหนดไว้ในRFC 3986

อักขระอื่น ๆ ทั้งหมดสามารถใช้ใน URL โดยมีเงื่อนไขว่าเป็น "URL ที่เข้ารหัส" ก่อน สิ่งนี้เกี่ยวข้องกับการเปลี่ยนอักขระที่ไม่ถูกต้องสำหรับ "รหัส" เฉพาะ (โดยปกติจะอยู่ในรูปแบบของสัญลักษณ์เปอร์เซ็นต์ (%) ตามด้วยตัวเลขฐานสิบหก)

ลิงค์นี้อ้างอิงการเข้ารหัส HTML URLมีรายการการเข้ารหัสสำหรับอักขระที่ไม่ถูกต้อง


และสำหรับอักขระ Unicodeบทความ Wikipedia Percent-encodingกล่าวว่า: "ไวยากรณ์ URI ทั่วไปกำหนดว่ารูปแบบ URI ใหม่ที่ให้สำหรับการแสดงข้อมูลอักขระใน URI ต้องแทนอักขระจากชุดที่ไม่ได้จองไว้โดยไม่มีการแปลและควรแปลงอักขระอื่น ๆ เป็นไบต์ตาม UTF-8 แล้วเข้ารหัสเปอร์เซ็นต์ค่าเหล่านั้น "
DavidRR

9

ช่วงอักขระ 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


5

ฉันต้องเลือกตัวละครเพื่อแยก URL เป็นสตริงดังนั้นฉันจึงตัดสินใจสร้างรายการอักขระที่ไม่สามารถหาได้ใน URL ด้วยตัวเอง:

>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'

"<>{}^|ดังนั้นทางเลือกที่เป็นไปได้ที่จะมีขึ้นบรรทัดใหม่แท็บพื้นที่ทับขวาและ ฉันเดาว่าฉันจะไปกับพื้นที่หรือขึ้นบรรทัดใหม่ :)


2

ไม่ใช่คำตอบสำหรับคำถามของคุณ แต่การตรวจสอบความถูกต้องของ url นั้นเป็น pita ที่ร้ายแรงคุณน่าจะตรวจสอบความถูกต้องของชื่อโดเมนและปล่อยให้แบบสอบถามเป็นส่วนหนึ่งของ url นั่นคือประสบการณ์ของฉัน นอกจากนี้คุณยังสามารถใช้วิธีส่ง Ping URL และดูว่ามันส่งผลในการตอบสนองที่ถูกต้อง แต่อาจจะมากเกินไปสำหรับงานง่าย ๆ

นิพจน์ทั่วไปในการตรวจจับ URL มีมากมาย google it :)



คำตอบนี้แนะนำว่าการตรวจสอบ URL ที่เป็นงานไม่ได้สำหรับ regex แต่สำหรับห้องสมุดภาษา / เฉพาะแพลตฟอร์ม
DavidRR

0

ฉันกำลังใช้คำขอ 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-และ


-4

ฉันมากับการแสดงออกปกติสำหรับ 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) );


4
-1; นอกเหนือจากข้อเท็จจริงที่ว่าทั้งคู่เกี่ยวข้องกับ URL ในความสามารถบางอย่างนี่ไม่เกี่ยวข้องกับคำถามที่ถูกถาม
Mark Amery
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.