URL ได้รับอนุญาตให้มีช่องว่างหรือไม่


132

URI (โดยเฉพาะ HTTP URL) ได้รับอนุญาตให้มีอักขระเว้นวรรคอย่างน้อยหนึ่งตัวหรือไม่? หากต้องเข้ารหัสURL เป็น+เพียงรูปแบบที่ปฏิบัติตามกันทั่วไปหรือเป็นทางเลือกอื่นที่ถูกต้อง?

โดยเฉพาะอย่างยิ่งใครบางคนสามารถชี้ไปที่ RFC ที่ระบุว่าต้องเข้ารหัสURL ที่มีช่องว่างได้หรือไม่

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


superset ที่มาในภายหลัง: ตัวอักษรที่ไม่ถูกต้องคืออะไร: stackoverflow.com/questions/1547899/…
Ciro Santilli 郝海东郝海东冠状病事件法轮功

คำตอบ:


101

ตามRFC 1738 :

ที่ไม่ปลอดภัย:

อักขระอาจไม่ปลอดภัยได้จากหลายสาเหตุ อักขระช่องว่างไม่ปลอดภัยเนื่องจากช่องว่างที่สำคัญอาจหายไปและอาจมีการเว้นช่องว่างที่ไม่มีนัยสำคัญเมื่อมีการถอดเสียง URL หรือเรียงพิมพ์หรืออยู่ภายใต้การดูแลของโปรแกรมประมวลผลคำ อักขระ"<"และ">"ไม่ปลอดภัยเนื่องจากใช้เป็นตัวคั่นรอบ URL ในข้อความอิสระ เครื่องหมายคำพูด ( """) ใช้เพื่อคั่น URL ในบางระบบ อักขระ"#"ไม่ปลอดภัยและควรเข้ารหัสเสมอเนื่องจากถูกใช้ในเวิลด์ไวด์เว็บและในระบบอื่น ๆ เพื่อคั่น URL จากตัวระบุแฟรกเมนต์ / แองเคอร์ที่อาจตามมา บทบาท"%"ไม่ปลอดภัยเนื่องจากใช้สำหรับการเข้ารหัสอักขระอื่น อักขระอื่นไม่ปลอดภัยเนื่องจากเกตเวย์และตัวแทนการขนส่งอื่น ๆ เป็นที่ทราบกันดีว่าบางครั้งแก้ไขอักขระดังกล่าว ตัวละครเหล่านี้มี"{", "}", "|", "\", "^", "~", "[", และ"]""`"

อักขระที่ไม่ปลอดภัยทั้งหมดจะต้องเข้ารหัสภายใน URLเสมอ ตัวอย่างเช่น"#"ต้องเข้ารหัสอักขระภายใน URL แม้ว่าในระบบที่ปกติจะไม่จัดการกับแฟรกเมนต์หรือตัวระบุจุดยึดดังนั้นหากคัดลอก URL ไปยังระบบอื่นที่ใช้อักขระเหล่านี้ก็ไม่จำเป็นต้องเปลี่ยนการเข้ารหัส URL


2
1738 ได้รับการดำเนินการเหนือกว่า 2396 ietf.org/rfc/rfc2396.txtนั่นคือข้อกำหนด Uri ในปัจจุบัน มันไม่สำคัญในกรณีนี้แม้ว่า
Steve Severance

40
และ 2396 ถูกแทนที่ด้วย 3986 หลายคนเข้าใจผิดเนื่องจาก RFC ไม่เปลี่ยนรูปจึงไม่ได้บอกผู้อ่านว่าพวกเขาล้าสมัยแล้ว คำแนะนำ: ใช้tools.ietf.org/html/rfcnnnnเช่นtools.ietf.org/html/rfc2396แทนโดยจะแสดงข้อมูลเมตาที่ขาดหายไปด้านบน
Julian Reschke

43

ทำไมถึงต้องเข้ารหัส? คำขอมีลักษณะดังนี้:

GET /url HTTP/1.1
(Ignoring headers)

มีช่อง 3 ช่องคั่นด้วยช่องว่างสีขาว หากคุณใส่ช่องว่างใน url ของคุณ:

GET /url end_url HTTP/1.1

คุณทราบว่ามี 4 ช่องเซิร์ฟเวอร์ HTTP จะแจ้งว่าเป็นคำขอที่ไม่ถูกต้อง

GET /url%20end_url HTTP/1.1

3 ช่อง => ถูกต้อง

หมายเหตุ: ในสตริงข้อความค้นหา (หลัง?) โดยปกติช่องว่างจะถูกเข้ารหัสเป็น +

GET /url?var=foo+bar HTTP/1.1 

ค่อนข้างมากกว่า

GET /url?var=foo%20bar HTTP/1.1 

จะเกิดอะไรขึ้นถ้า var เป็น "foo + bar" ไม่ใช่ "foo bar" ล่ะ?
Ivo3185

2
ฉันขอยืนยันว่าเป็นข้อกำหนดของเลเยอร์การขนส่งไม่ใช่ของข้อกำหนด URI เอง เห็นได้ชัดว่า GET เป็นคุณสมบัติของ http: specification ไม่ใช่ข้อกำหนด URL ในทำนองเดียวกันคุณสามารถโต้แย้งคำพูดใน URL ที่ "ต้อง" ได้รับการเข้ารหัสเพราะไม่เช่นนั้นหน้าเว็บจะพัง แต่นั่นเป็นคุณสมบัติของข้อ จำกัด การจัดรูปแบบ HTML (ซึ่งมีกลยุทธ์อื่น ๆ ต่อต้าน) ไม่ใช่คุณสมบัติของข้อกำหนด URL
Kent Fredric

ietf.org/rfc/rfc1738.txt - อักขระที่ไม่ปลอดภัยรวมถึงช่องว่าง) ควรเข้ารหัส
Julien

@KentFredric นี่เป็นเลเยอร์การนำเสนอที่เป็นไปได้มากกว่าไม่ใช่เลเยอร์การขนส่ง ดังที่Julien (เกือบ) เขียนข้อกำหนด URI ดั้งเดิม ( RFC 1630 ) มีข้อ จำกัด นี้ดังนั้นจึงเป็นส่วนหนึ่งของข้อกำหนด URI โดยไม่คำนึงถึงความรู้สึกส่วนตัวของคุณ เนื่องจากข้อมูลจำเพาะ URI ถูกเขียนขึ้นหลังจากการร่าง HTTP จึงเป็นไปได้มากที่ URI ได้รับการออกแบบโดยคำนึงถึง HTTP รวมถึงการห้ามไม่ให้ใช้ช่องว่าง แต่มันก็ไม่สำคัญใช่ไหม ความจริงก็คือสเป็คว่าสเป็คเป็นอย่างไร
Christopher Schultz

38

คำตอบสั้นกว่า: ไม่คุณต้องเข้ารหัสช่องว่าง มันเป็นที่ถูกต้องในการเข้ารหัสพื้นที่เป็น+แต่เพียงในสตริงแบบสอบถาม; %20ในเส้นทางที่คุณต้องใช้


1
สวัสดีฉันก็งงเหมือนกันบางครั้งฉันเห็นหนังสือเล่มนี้ใช้ "+" แต่บางครั้งก็เป็น "% 20" ช่วยดูตัวอย่างนี้หน่อยได้ไหม เมื่อผู้ใช้ส่งแบบฟอร์มฟอร์มเข้ารหัสพื้นที่อย่างไร? กับตัวละครไหน?
GMsoF

1
ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติม
DavidRR

ส่วนแฟรกเมนต์ / แฮชล่ะ ควรเข้ารหัสช่องว่างที่นั่นอย่างไร
gumkins

@gumkins: ส่วนย่อย (# และหลัง) ไม่ถูกส่งไปยังเซิร์ฟเวอร์ ในทางปฏิบัติคุณสามารถใช้% 20 หรือ + ที่ใดก็ได้เพื่อเข้ารหัสช่องว่าง
Julien

9

URL ถูกกำหนดในRFC 3986แม้ว่า RFC อื่น ๆ ก็เกี่ยวข้องเช่นกัน แต่RFC 1738ล้าสมัย

อาจไม่มีช่องว่างพร้อมกับอักขระอื่น ๆ อีกมากมาย เนื่องจากอักขระต้องห้ามเหล่านั้นมักจะต้องแสดงอย่างใดอย่างหนึ่งจึงมีรูปแบบสำหรับการเข้ารหัสเป็น URL โดยการแปลเป็นเลขฐานสิบหก ASCII โดยมีคำนำหน้า "%"

ภาษา / แพลตฟอร์มการเขียนโปรแกรมส่วนใหญ่มีฟังก์ชันสำหรับการเข้ารหัสและถอดรหัส URL แม้ว่าอาจไม่เป็นไปตามมาตรฐาน RFC อย่างถูกต้อง ตัวอย่างเช่นฉันรู้ว่า PHP ไม่


7

ใช่พื้นที่มักจะเข้ารหัสเป็น "% 20" พารามิเตอร์ใด ๆ ที่ส่งไปยัง URL ควรได้รับการเข้ารหัสเพียงเพื่อความปลอดภัย


6

URL สามารถมีอักขระช่องว่างอยู่ในนั้นและจะแสดงเป็น% 20 ในเบราว์เซอร์ส่วนใหญ่ แต่กฎการเข้ารหัสของเบราว์เซอร์มีการเปลี่ยนแปลงค่อนข้างบ่อยและเราไม่สามารถขึ้นอยู่กับว่าเบราว์เซอร์จะแสดง URL อย่างไร

ดังนั้นคุณสามารถแทนที่อักขระช่องว่างใน URL ด้วยอักขระใดก็ได้ที่คุณคิดว่าจะทำให้ URL อ่านง่ายขึ้นและ 'สวย';) ..... O ดังนั้นอักขระทั่วไปที่ต้องการคือ "-", "_", "+" .... แต่สิ่งเหล่านี้ไม่ใช่การบังคับดังนั้นคุณสามารถใช้อักขระใด ๆ ที่ไม่ควรมีอยู่ใน URL แล้ว

โปรดหลีกเลี่ยง%, &,}, {,], [, /,>, <เป็นการแทนที่อักขระช่องว่าง URL เนื่องจากอาจทำให้เกิดข้อผิดพลาดในเบราว์เซอร์และแพลตฟอร์มบางอย่างได้

อย่างที่คุณเห็น Stak overflow นั้นใช้อักขระ "-" แทน Space (% 20)

มีความสุขในการตั้งคำถาม



5

ใครสามารถชี้ไปที่ RFC ที่ระบุว่าต้องเข้ารหัส URL ที่มีช่องว่าง

URI และด้วยเหตุนี้ URL จึงถูกกำหนดใน RFC 3986

หากคุณดูไวยากรณ์ที่กำหนดไว้ที่นั่นในที่สุดคุณจะสังเกตได้ว่าอักขระช่องว่างไม่สามารถเป็นส่วนหนึ่งของ URL ทางกฎหมายเชิงไวยากรณ์ได้ดังนั้นคำว่า "URL ที่มีช่องว่าง" จึงมีความขัดแย้งในตัวเอง


3

เพื่อตอบคำถามของคุณ ฉันจะบอกว่ามันเป็นเรื่องปกติที่แอปพลิเคชันจะแทนที่ช่องว่างในค่าที่จะใช้ใน URL เหตุผลนี้คือเรามักจะหลีกเลี่ยงการเข้ารหัสเปอร์เซ็นต์ (URI) ที่อ่านยากกว่าที่เกิดขึ้น

ตรวจสอบบทความวิกิพีเดียเกี่ยวกับการเข้ารหัสเปอร์เซ็นต์


2

Firefox 3 จะแสดง%20s ใน URL เป็นช่องว่างในแถบที่อยู่


"Is a URL allowed to contain a space?"นี้ไม่ได้เป็นคำตอบที่เหมาะสมสำหรับคำถามตรงไปตรงสวย: ค่อนข้างแสดงความคิดเห็น
Roko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.