เมื่อเข้ารหัสพื้นที่เป็นบวก (+) หรือ% 20


487

บางครั้งพื้นที่ได้รับการเข้ารหัส URL กับ+สัญญาณบางครั้งอื่น ๆ %20ที่จะ ความแตกต่างคืออะไรและทำไมจึงควรเกิดขึ้น


คำตอบ:


481

+หมายถึงพื้นที่เฉพาะในapplication/x-www-form-urlencodedเนื้อหาเช่นส่วนแบบสอบถามของ URL ที่:

http://www.example.com/path/foo+bar/path?query+name=query+value

ใน URL นี้ชื่อพารามิเตอร์คือquery nameมีช่องว่างและความคุ้มค่าคือquery valueมีพื้นที่ แต่ชื่อโฟลเดอร์ในเส้นทางเป็นตัวอักษรfoo+bar, ไม่ foo bar

%20เป็นวิธีที่ถูกต้องในการเข้ารหัสช่องว่างในบริบทเหล่านี้ ดังนั้นหากคุณต้องการที่จะเข้ารหัส URL สตริงเพื่อรวมไว้ในส่วนของ URL ที่เป็นเสมอปลอดภัยในการเปลี่ยนการเว้นวรรค%20และ pluses %2Bกับ นี่คือสิ่งที่เช่น encodeURIComponent()ทำใน JavaScript โชคไม่ดีที่urlencodeนั้นทำใน PHP ( rawurlencodeนั้นปลอดภัยกว่า)

ดูเพิ่มเติม HTML Application ข้อมูลจำเพาะ 4.01 / x-www-form-urlencoded


5
ฉันสับสนจริง ๆ คำถามของฉันคือเมื่อเบราว์เซอร์ทำรูปแบบแรกและเมื่อไหร่ที่ fomr ที่สอง
มูฮัมหมัด Hewedy

11
เบราว์เซอร์จะสร้างพารามิเตอร์จากรูปแบบที่มีquery+name=query+value <input name="query name" value="query value">มันจะไม่สร้างquery%20nameจากแบบฟอร์ม แต่ปลอดภัยโดยสิ้นเชิงที่จะใช้สิ่งนั้นแทนเช่น หากคุณกำลังส่งแบบฟอร์มด้วยกันXMLHttpRequestคุณจะได้รับ หากคุณมี URL ที่มีช่องว่างใน<a href="http://www.example.com/foo bar/">นั้นเบราว์เซอร์จะเข้ารหัสสิ่งนั้นเพื่อ%20ให้คุณแก้ไขข้อผิดพลาด แต่นั่นอาจไม่ใช่วิธีที่ดีที่สุด
bobince

6
สิ่งที่ฟังก์ชั่นบน javascript ทำfoo barเพื่อfoo+bar?
Sisir

21
@Sisir: ไม่มีฟังก์ชัน JS ที่จะทำการเข้ารหัส URL คุณสามารถทำได้โดยธรรมชาติencodeURIComponent(s).replace(/%20/g, '+')ถ้าคุณต้องการจริงๆ+
bobince

2
นั่นเป็นตัวอย่างที่สับสนมาก ๆ ของบางสิ่งที่เป็นแบบฟอร์ม urlencoded ไม่มีส่วนเกี่ยวข้องกับ URL
Dave Van den Eynde

54

http://www.example.com/some/path/to/resource?param1=value1

ส่วนที่อยู่หน้าเครื่องหมายคำถามต้องใช้การเข้ารหัส% (เพื่อ%20เว้นวรรค) หลังจากเครื่องหมายคำถามคุณสามารถใช้ช่องว่าง%20หรือ+ช่องว่างก็ได้ หากคุณต้องการที่เกิดขึ้นจริงหลังจากใช้เครื่องหมายคำถาม+%2B


6
@DaveVandenEynde ทำไมล่ะ
cerberos

10
เพราะมันผิด เป็นส่วนหนึ่งของประเภทสื่อเก่า / x-www-form-urlencoded ที่ไม่ได้ใช้กับ URL นอกจากนี้decodeURIComponentอย่าถอดรหัสมัน
Dave Van den Eynde

3
ใช่มันอาจจะคัดลอกมาจาก RFC 1630 และไม่เคยเป็นมาตรฐานจริงๆ tools.ietf.org/html/rfc3986เป็นมาตรฐาน (อัปเดตอีกครั้งสำหรับ IPv6 หรือบางอย่าง) แน่ใจว่าเบราว์เซอร์ยังคง "สนับสนุน" แต่สิ่งนี้หมายความว่าอย่างไร อาจเป็นเซิร์ฟเวอร์หรือรหัสลูกค้าที่อ่านสตริงการสืบค้นและถอดรหัสไม่ใช่เบราว์เซอร์ เบราว์เซอร์จะส่งผ่านไปมาและเนื่องจาก+เป็นอักขระที่สงวนไว้เบราว์เซอร์จะถูกเก็บรักษาไว้
Dave Van den Eynde

18
Google ใช้ช่องว่างของ + ใน URL การค้นหา ( google.com/#q=perl+equivalent+to+php+urlencode+spaces+as+%2B )
Justin

2
FYI: Rails ยังถอดรหัสช่องว่างด้วย+โดยค่าเริ่มต้น ( { foo: 'bar bar'}.to_query=> foo=bar+bar)
wrtsprt

46

ดังนั้นคำตอบที่นี่ทั้งหมดไม่สมบูรณ์เล็กน้อย การใช้ '% 20' เพื่อเข้ารหัสช่องว่างใน URL ถูกกำหนดไว้อย่างชัดเจนในRFC3986ซึ่งกำหนดวิธีการสร้าง URI ไม่มีการกล่าวถึงในข้อกำหนดของการใช้ '+' สำหรับการเข้ารหัสช่องว่าง - หากคุณไปตามข้อกำหนดนี้เพียงอย่างเดียวพื้นที่จะต้องถูกเข้ารหัสเป็น '% 20'

การกล่าวถึงการใช้ '+' สำหรับการเข้ารหัสช่องว่างนั้นมาจากการแปลงข้อมูลจำเพาะต่างๆของ HTML - โดยเฉพาะในส่วนที่อธิบายถึงประเภทเนื้อหา 'application / x-www-form-urlencoded' ใช้สำหรับการโพสต์ข้อมูลในแบบฟอร์ม

ตอนนี้ข้อมูลจำเพาะ HTML 2.0 (RFC1866) ได้กล่าวไว้อย่างชัดเจนในหัวข้อ 8.2.2 ว่าส่วนการสืบค้นของสตริง URL ของคำขอ GET ควรถูกเข้ารหัสเป็น 'application / x-www-form-urlencoded' ตามทฤษฎีแล้วแสดงให้เห็นว่าการใช้ '+' ใน URL ในสตริงการสืบค้นนั้นถูกต้องตามกฎหมาย (หลังจาก '?')

แต่ ... มันจริงเหรอ? โปรดจำไว้ว่า HTML เป็นตัวกำหนดเนื้อหาและ URL ที่มีสตริงข้อความค้นหาสามารถใช้กับเนื้อหาอื่นที่ไม่ใช่ HTML นอกจากนี้ในขณะที่รุ่นที่ใหม่กว่าของข้อมูลจำเพาะ HTML ยังคงกำหนด '+' ตามกฎหมายใน 'application / x-www-form-urlencoded' เนื้อหาพวกเขาละเว้นส่วนที่ระบุว่าได้รับการกำหนดสตริงคำขอแบบสอบถาม GET เป็นประเภทนั้น ในความเป็นจริงไม่มีการพูดถึงสิ่งใดเกี่ยวกับการเข้ารหัสสตริงแบบสอบถามในสิ่งใด ๆ หลังจากข้อมูลจำเพาะ HTML 2.0

ซึ่งทำให้เรามีคำถาม - มันถูกต้อง? แน่นอนว่ามีรหัสดั้งเดิมจำนวนมากที่รองรับ '+' ในสตริงการสืบค้นและมีรหัสจำนวนมากที่สร้างขึ้นเช่นกัน ดังนั้นราคาจะดีคุณจะไม่ผิดหากคุณใช้ '+' (และในความเป็นจริงฉันได้ทำการวิจัยทั้งหมดเมื่อเร็ว ๆ นี้เพราะฉันค้นพบเว็บไซต์หลักที่ไม่สามารถยอมรับ '% 20' ในแบบสอบถาม GET เป็นช่องว่างได้จริง ๆ แล้วพวกเขาล้มเหลวในการถอดรหัสอักขระที่เข้ารหัสร้อยละใด ๆ ดังนั้นบริการคุณ การใช้งานอาจมีความเกี่ยวข้องเช่นกัน)

แต่จากการอ่านข้อมูลจำเพาะอย่างละเอียดหากไม่มีภาษาจากข้อกำหนด HTML 2.0 ที่นำไปใช้ในเวอร์ชั่นที่ใหม่กว่า URL จะถูกครอบคลุมโดย RFC3986 ซึ่งหมายความว่าช่องว่างควรจะถูกแปลงเป็น '% 20' และแน่นอนว่าควรเป็นเช่นนั้นหากคุณร้องขอสิ่งอื่นนอกเหนือจากเอกสาร HTML


หากต้องการเพิ่มคำตอบของคุณ Chrome โดยค่าเริ่มต้นจะเข้ารหัสช่องว่างใน URL เป็น%20( <a href="?q=a b">) แต่เมื่อคุณส่งแบบฟอร์มจะใช้+เครื่องหมาย คุณสามารถแทนที่ว่าโดยชัดเจนโดยใช้+เครื่องหมาย ( <a href="?q=a+b">) XMLHTTPRequestหรือโดยการส่งแบบฟอร์มโดยใช้
x-yuri

เป็นการยากที่จะเข้าใจจุดประสงค์ของการเพิ่ม URLSearchParams developers.google.com/web/updates/2016/01/urlsearchparamsซึ่งทำงานในลักษณะที่สืบทอดกันมา (ทำให้ซีเรียล SPACE เป็น '+') มันยังไม่รองรับใน IE11!
Nymphetamine

9

มันจะดีกว่าที่จะเข้ารหัสช่องว่างเป็น% 20 เสมอไม่ใช่ "+"

เป็น RFC-1866 (ข้อมูลจำเพาะ HTML 2.0) ซึ่งระบุว่าอักขระช่องว่างควรเข้ารหัสเป็น "+" ใน "application / x-www-form-urlencoded" คู่ประเภทคีย์ - ค่าเนื้อหา (ดูย่อหน้า 8.2.1. อนุวรรค 1) วิธีการเข้ารหัสข้อมูลในแบบฟอร์มนี้ยังให้ไว้ในข้อกำหนด HTML ในภายหลังค้นหาย่อหน้าที่เกี่ยวข้องเกี่ยวกับ application / x-www-form-urlencoded

นี่คือตัวอย่างของสตริงดังกล่าวใน URL ที่ RFC-1866 อนุญาตให้เข้ารหัสพื้นที่เป็น pluses: "http://example.com/over/there?name=foo+bar" ดังนั้นหลังจาก "?" ช่องว่างสามารถถูกแทนที่ด้วย pluses ตาม RFC-1866 ในกรณีอื่น ๆ ช่องว่างควรเข้ารหัสเป็น% 20 แต่เนื่องจากเป็นการยากที่จะกำหนดบริบทจึงเป็นวิธีที่ดีที่สุดที่จะไม่เข้ารหัสช่องว่างเป็น "+"

ฉันขอแนะนำให้เข้ารหัสเปอร์เซ็นต์อักขระทั้งหมดยกเว้น "unreserved" ที่กำหนดใน RFC-3986, p.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

1
ใน. Net Framework UrlEncode ใช้ '+' ใน QueryString แต่ใช้. Net Core% 20 ที่ทันสมัย
Michael Freidgeim

@ MiFreidgeimSO-stopbeingevil ขอบคุณที่แจ้งให้เราทราบ ดูเหมือนว่า. Net Core ที่ทันสมัยจะมีความสอดคล้องและเข้ากันได้มากขึ้น
Maxim Masiutin

2

ความแตกต่างคืออะไร: ดูคำตอบอื่น ๆ

เมื่อใช้+แทน%20? ใช้+ถ้าด้วยเหตุผลบางอย่างคุณต้องการทำให้สตริงการสืบค้น URL ( ?.....) หรือส่วนแฮช ( #....) อ่านง่ายขึ้น ตัวอย่าง: คุณสามารถอ่านสิ่งนี้ได้จริง:

https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces ( %2B= +)

แต่ข้อความต่อไปนี้อ่านยากกว่ามาก: (อย่างน้อยสำหรับฉัน)

https://www.google.se/#q=google%20doesn%27t%20oops%20:%20%20this%20text%20%2B%20is%20different%20spaces

ฉันคิดว่า+ไม่น่าจะทำลายอะไรเลยเนื่องจาก Google ใช้+(ดูลิงก์ที่ 1 ด้านบน) และพวกเขาอาจคิดเกี่ยวกับเรื่องนี้ ฉันจะใช้+ตัวเองเพราะอ่านได้ + Google คิดว่าไม่เป็นไร


7
ฉันว่าอาร์กิวเมนต์ "การอ่านได้" เป็นการป้องกันที่ดีที่สุดสำหรับ '+' อาร์กิวเมนต์ "google
do

2
@FlipMcF หน้าวิกิพีเดียโต้แย้งจากผู้มีอำนาจผิดเกี่ยวกับ "เมื่อผู้มีอำนาจอ้างถึงในหัวข้อที่อยู่นอกพื้นที่ของความเชี่ยวชาญของพวกเขาหรือเมื่อผู้มีอำนาจอ้างถึงไม่ใช่ผู้เชี่ยวชาญที่แท้จริง " - ฉันคิดว่าคอมพิวเตอร์ HTTP และ URL การเข้ารหัสเป็นสิ่งที่อยู่ในความเชี่ยวชาญของ Google
KajMagnus

3
@FlipMcF อ้างถึงพฤติกรรมของ Google ในกรณีนี้เป็นอาร์กิวเมนต์ที่ถูกต้องในการใช้ "+" ใน URL ไม่ใช่ว่า Google เป็นองค์กร แต่ Google นั้นน่าจะเป็น บริษัท อินเทอร์เน็ตรายใหญ่ที่สุดและหากพวกเขาทำบางอย่างมันก็ไม่น่าเป็นไปได้สูงที่วันหนึ่งเบราว์เซอร์จะตัดสินใจหยุดสนับสนุนการปฏิบัติเช่นนั้น นอกจากนี้ google chrome เป็นหนึ่งในเบราว์เซอร์ที่มีส่วนแบ่งสูงสุดและพวกเขาจะสนับสนุนสิ่งที่ google ต้องการ โดยรวมแล้วฉันบอกว่าไม่มีใครที่ใช้ "+" แทน "% 20" จะมีช่วงเวลาที่ลำบากเพราะในอนาคตอันใกล้
jdferreira

ฉันชอบที่จะโต้แย้งเรื่องนี้ต่อไปที่อื่นซึ่งมีการอุทธรณ์ถึงความนิยมที่จะปฏิเสธที่จะยอมรับการอุทธรณ์ต่อผู้มีอำนาจ อย่างน้อยเราก็เห็นด้วยกับสิ่งหนึ่ง: '+' เหนือกว่า '% 20'
FlipMcF

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