ฉันเข้ารหัสแอมป์แซนด์ใน <a href…>หรือไม่


157

ฉันกำลังเขียนโค้ดที่สร้าง HTML ขึ้นมาโดยอัตโนมัติและฉันต้องการให้เข้ารหัสอย่างถูกต้อง

ว่าฉันกำลังสร้างลิงค์ไปยัง URL ต่อไปนี้:

http://www.google.com/search?rls=en&q=stack+overflow

ฉันสมมติว่าค่าแอตทริบิวต์ทั้งหมดควรเป็นแบบ HTML (โปรดแก้ไขให้ฉันถ้าฉันผิด) ดังนั้นนั่นหมายความว่าถ้าฉันใส่ URL ด้านบนลงในแท็กจุดยึดฉันควรเข้ารหัสเครื่องหมายและเป็น&amp;ดังนี้:

<a href="http://www.google.com/search?rls=en&amp;q=stack+overflow">

ถูกต้องหรือไม่



6
@CiroSantilli: เกี่ยวกับสตริง URL จริง นี่เป็นเรื่องเกี่ยวกับวิธีการเข้ารหัสเมื่อปรากฏในแอตทริบิวต์ HTML
เจดับบลิว

อย่างที่ฉันเห็นการเข้ารหัสเครื่องหมายแอมเปอร์แซนด์ไม่จำเป็นเสมอไปใน html5 และคำตอบล้าสมัย
qdinar

1
คำถามสำหรับ html5: stackoverflow.com/questions/19441750/…
qdinar

คำตอบ:


175

ใช่แล้ว. เอนทิตี HTML ถูกแยกวิเคราะห์ภายในแอตทริบิวต์ HTML และจรจัด&จะสร้างความกำกวม นั่นเป็นเหตุผลที่คุณควรเขียน&amp;แทนเพียง&ภายในทั้งหมดแอตทริบิวต์ HTML

ที่กล่าวเท่านั้น&และราคาจะต้องมีการเข้ารหัส หากคุณมีอักขระพิเศษเช่นเดียวกับéในแอตทริบิวต์ของคุณคุณไม่จำเป็นต้องเข้ารหัสเพื่อตอบสนองตัวแยกวิเคราะห์ HTML

จะใช้เป็นกรณีที่ URL ที่จำเป็นในการรักษาพิเศษกับตัวละครที่ไม่ใช่ ASCII éเช่น คุณมีการเข้ารหัสที่ใช้ร้อยละหนีและในกรณีนี้ก็จะให้%C3%A9เพราะพวกเขาถูกกำหนดโดยRFC 1738 อย่างไรก็ตาม RFC 1738 ได้รับการแทนที่โดยRFC 3986 (URIs, Uniform Resource Identifier) ​​และRFC 3987 (IRIs, Internationalized Resource Identifiers) ซึ่งWhatWG ใช้งานเพื่อกำหนดว่าเบราว์เซอร์ควรทำงานอย่างไรเมื่อพวกเขาเห็น URL ที่ไม่ใช่ ASCII ตัวละครในมันตั้งแต่ HTML5 ดังนั้นจึงปลอดภัยที่จะรวมอักขระที่ไม่ใช่ ASCII ใน URL เข้ารหัสเปอร์เซ็นต์หรือไม่


1
ฉันค่อนข้างแน่ใจในเรื่องนี้ แต่ฉันมีช่วงเวลาที่สงสัย ขอบคุณสำหรับการยืนยัน
เจดับบลิว

1
คุณสามารถเข้ารหัสช่องว่างเป็น "+" แทนที่จะเป็น% 20 ซึ่งทำให้ URL อ่านง่ายขึ้น
NickG

1
+ ไม่ได้รับความเคารพในลิงก์ mailto ในโปรแกรมรับส่งเมล iPhone ในพื้นที่สำหรับสิ่งที่คุ้มค่า
Ryan Olson

1
éยังคงต้องการการเข้ารหัส: stackoverflow.com/questions/2742852/unicode-characters-in-urls
lulalala

4
ฉันจะเพิ่ม (เพราะฉันเพิ่งตกอยู่ในข้อผิดพลาดนี้) ว่าถ้าคุณอาศัยแม่แบบเอ็นจิ้นคุณควรตรวจสอบว่ามันจะดูแลการหลบหนีเอนทิตี HTML โดยอัตโนมัติหรือไม่ ในกรณีของฉันทวิทำนั้นและผมก็ผิดสองครั้งที่หลบหนีการเขียนลงในแอตทริบิวต์แท็กแทนการใช้โดยตรง&amp; &
Kamafeather

24

ตามคำแนะนำ HTML อย่างเป็นทางการในปัจจุบันต้องใช้เครื่องหมายแอมเปอร์แซนด์เช่น&amp;ในบริบทเช่นนี้ อย่างไรก็ตามเบราว์เซอร์ไม่จำเป็นต้องใช้และ HTML5 CR เสนอให้สร้างกฎนี้เพื่อให้ใช้กฎพิเศษในค่าแอตทริบิวต์ เครื่องมือตรวจสอบ HTML5 ปัจจุบันล้าสมัยในแง่นี้ (ดูรายงานข้อผิดพลาดพร้อมความคิดเห็น)

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


4
XHTML (XHTML จริงที่ส่งเป็นapplication/xhtml+xml) มักเป็นสิ่งที่ต้องการเสมอ
zneak

4
ข้อแม้ประการหนึ่งเกี่ยวกับการเปลี่ยนแปลงนี้ซึ่งยังคงมีการหารือถกเถียงและเข้าใจผิดว่า&เป็นสิ่งที่ควรจะเป็นตอนนี้ตราบใดที่มันเป็น " ไม่ชัดเจน" วิธีหนึ่งที่ชัดเจนในการทำให้เครื่องหมายแอมเปอร์แซนด์คลุมเครือคือการตามด้วยอักขระที่ไม่ใช่ช่องว่างก่อนแล้วจึงใช้เครื่องหมายอัฒภาค เครื่องหมายแอมเปอร์แซนด์นั้นคลุมเครือและจะทำให้เกิดข้อผิดพลาดในการแยกวิเคราะห์
matty

ดังที่ Jukka กล่าวมีความเสี่ยงที่จะเข้ารหัสแอมป์แซนด์ทั้งหมดดังนั้นให้พิจารณาว่ามีความเป็นไปได้ที่ URL href ของคุณจะมีเครื่องหมายอัฒภาคอยู่หรือไม่ ค่อนข้างไม่น่าเป็นเพราะฉันไม่แน่ใจว่าฉันเคยเห็น URL ที่มีเครื่องหมายอัฒภาค ไม่ว่าจะทำไม่ได้ ดังนั้นในทางปฏิบัติที่พูดฉันไม่คิดว่ามันเป็นไปได้ว่าการใช้งานของ&เราจะไม่ชัดเจน ดังนั้นเราจึงยังคงใช้มันไม่ได้เข้ารหัสในคุณลักษณะ href
matty

เหตุผลทั้งหมดหนีเป็นสิ่งที่จำเป็นเป็นอย่างแม่นยำเพราะเป็นไปได้ของความคลุมเครือ ปัญหาเฉพาะนี้อาจไม่แนะนำให้ใช้เวกเตอร์การโจมตี XSS การเรนเดอร์ที่ไม่ดีหรือผลกระทบใด ๆ ที่ 99.99% ของเวลาทั้งหมด แต่นั่นไม่ใช่เหตุผลที่จะไม่รบกวน การหลบหนีอย่างถูกต้องนั้นทำได้ยากและมีความเป็นไปได้ที่จะทำผิดพลาดอยู่เสมอ
Phil

5

ฉันกำลังโพสต์คำตอบใหม่เพราะฉันพบว่าคำตอบของ zneak ไม่มีตัวอย่างเพียงพอไม่แสดงการจัดการ HTML และ URI เป็นแง่มุมและมาตรฐานที่แตกต่างกันและมีบางสิ่งที่ขาดหายไปเล็กน้อย

คุณมีสองมาตรฐานเกี่ยวกับ URL ในลิงค์ (<a href )

มาตรฐานแรกคือRFC 1866 (HTML 2.0) ที่อยู่ใน "3.2.1. Data Characters" คุณสามารถอ่านอักขระที่จำเป็นต้องหลีกเลี่ยงเมื่อใช้เป็นค่าสำหรับแอตทริบิวต์ HTML (แอตทริบิวต์เองไม่อนุญาตให้ใช้อักขระพิเศษเลยเช่น<a hr&ef="http://...ไม่อนุญาตหรือ<a hr&amp;ef="http://...ไม่ใช่)

หลังจากนี้ได้เข้าสู่มาตรฐานHTML 4ตัวละครที่คุณต้องหลบหนีคือ:

<   to   &lt;
>   to   &gt;
&   to   &amp;
"   to   &quote;
'   to   &apos;

มาตรฐานอื่นคือRFC 3986 "มาตรฐาน URI ทั่วไป" ซึ่งจัดการ URL (สิ่งนี้เกิดขึ้นเมื่อเบราว์เซอร์กำลังจะติดตามลิงก์เนื่องจากผู้ใช้คลิกที่องค์ประกอบ HTML)

reserved    = gen-delims / sub-delims

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

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

มันเป็นสิ่งสำคัญที่จะหลีกเลี่ยงตัวละครเหล่านั้นเพื่อให้ลูกค้ารู้ว่าพวกเขาเป็นตัวแทนของข้อมูลหรือตัวคั่น

ตัวอย่างที่ไม่ใช้ Escape:

https://example.com/?user=test&password&te&st&goto=https://google.com

ตัวอย่าง URL ที่สมบูรณ์

https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com

ตัวอย่าง URL ที่ถูกต้องสมบูรณ์ในค่าของแอตทริบิวต์ HTML:

https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com

สถานการณ์ที่สำคัญเช่นกัน:

  • Javascript เป็นค่า:

    <img src="..." onclick="window.location.href = &quot;https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com&quot;;">...</a>(ใช่;;ถูกต้อง)

  • JSON เป็นค่า:

    <a href="..." data-analytics="{&quot;event&quot;: &quot;click&quot;}">...</a>

  • สิ่งที่หลบหนีภายในสิ่งที่หลบหนีการเข้ารหัสสองครั้ง URL ภายใน URL ภายในพารามิเตอร์ ฯลฯ ...

    http://x.com/?passwordUrl=http%3A%2F%2Fy.com%2F%3Fuser%3Dtest&amp;password=&quot;&quot;123


3

ใช่คุณควรแปลงไป&&amp;

เครื่องมือตรวจสอบ html นี้โดย W3Cมีประโยชน์สำหรับคำถามเช่นนี้ มันจะบอกคุณข้อผิดพลาดและคำเตือนสำหรับหน้าเฉพาะ


1
ฉันไม่แน่ใจว่าตัวตรวจสอบความถูกต้อง W3C ตรวจพบสิ่งนี้ (unescaped &in href) เป็นข้อผิดพลาด
ChrisW

6
ปัจจุบันเครื่องมือตรวจสอบ W3C ยอมรับการไม่ใช้ค่า Escape & เป็นข้อมูลที่ถูกต้อง หมายความว่ามาตรฐานมีการเปลี่ยนแปลงและไม่จำเป็นต้องเข้ารหัสอีกต่อไปหรือไม่ (ทำคำตอบส่วนใหญ่ล้าสมัยที่นี่)? ถ้าเป็นเช่นนี้สิ่งนี้ใช้ได้เฉพาะกับ href หรือแอตทริบิวต์ใด ๆ
matteo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.