ฉันต้องใช้ Content-Type: application / octet-stream เพื่อดาวน์โหลดไฟล์หรือไม่?


414

มาตรฐาน HTTPพูดว่า:

หากส่วนหัวนี้ [เนื้อหา - การจัดการ: สิ่งที่แนบมา] ถูกใช้ในการตอบกลับด้วย application / octet-stream content-type ข้อเสนอแนะโดยนัยคือตัวแทนผู้ใช้ไม่ควรแสดงการตอบสนอง แต่ป้อนโดยตรง `บันทึกการตอบสนองเป็น .. กล่องโต้ตอบ. '

ฉันอ่านมันเป็น

Content-Type: application/octet-stream
Content-Disposition: attachment

แต่ฉันคิดว่าContent-Typeจะเป็นapplication/pdfเช่นimage/pngนั้นเป็นต้น

ฉันควรจะทำContent-Type: application/octet-streamอย่างไรหากฉันต้องการให้เบราว์เซอร์ดาวน์โหลดไฟล์

คำตอบ:


959

เลขที่

ประเภทเนื้อหาควรเป็นสิ่งที่เป็นที่รู้จักกันถ้าคุณรู้ว่ามัน application/octet-streamถูกกำหนดให้เป็น "ข้อมูลไบนารีโดยพลการ" ใน RFC 2046 และมีการทับซ้อนกันที่นี่ซึ่งเหมาะสมสำหรับเอนทิตีที่มีจุดประสงค์เพียงอย่างเดียวคือการบันทึกลงดิสก์และจากจุดนั้นอยู่นอกเหนือสิ่งใด "webby" หรือมองจากอีกทิศทางหนึ่ง สิ่งเดียวที่สามารถทำได้อย่างปลอดภัยกับ application / octet-stream คือการบันทึกลงไฟล์และหวังว่าคนอื่นจะรู้ว่ามันคืออะไร

คุณสามารถรวมการใช้งานContent-Dispositionกับประเภทเนื้อหาอื่น ๆ เช่นimage/pngหรือแม้กระทั่งtext/htmlเพื่อระบุว่าคุณต้องการประหยัดแทนที่จะแสดง มันเคยเป็นกรณีที่บางเบราว์เซอร์จะไม่สนใจในกรณีของtext/htmlแต่ฉันคิดว่านี่เป็นเวลานานมาแล้ว ณ จุดนี้ (และฉันจะเข้านอนเร็ว ๆ นี้ดังนั้นฉันจะไม่เริ่มทดสอบทั้งกลุ่ม เบราว์เซอร์ในขณะนี้อาจช้า)

RFC 2616 ยังกล่าวถึงความเป็นไปได้ของโทเค็นส่วนขยายและวันนี้เบราว์เซอร์ส่วนใหญ่ยอมรับinlineว่าคุณต้องการให้เอนทิตีแสดงหากเป็นไปได้ (นั่นคือถ้าเป็นเบราว์เซอร์ประเภทที่รู้วิธีแสดงมิฉะนั้นจะไม่มีทางเลือก) . นี่เป็นพฤติกรรมเริ่มต้นแน่นอน แต่หมายความว่าคุณสามารถรวมfilenameส่วนหัวของเบราว์เซอร์ที่จะใช้ (อาจมีการปรับเปลี่ยนบางอย่างดังนั้นส่วนขยายไฟล์ตรงกับบรรทัดฐานของระบบในท้องถิ่นสำหรับประเภทเนื้อหาที่เป็นปัญหาอาจไม่) เป็นข้อเสนอแนะหากผู้ใช้พยายามบันทึก

ดังนั้น:

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="picture.png"

แปลว่า "ฉันไม่รู้ว่ามันคืออะไรโปรดบันทึกมันเป็นไฟล์โดยเฉพาะชื่อ picture.png"

Content-Type: image/png
Content-Disposition: attachment; filename="picture.png"

หมายถึง "นี่คือภาพ PNG โปรดบันทึกเป็นไฟล์โดยควรตั้งชื่อ picture.png"

Content-Type: image/png
Content-Disposition: inline; filename="picture.png"

หมายความว่า "นี่เป็นภาพ PNG โปรดแสดงถ้าคุณไม่ทราบวิธีการแสดงภาพ PNG ไม่เช่นนั้นหรือหากผู้ใช้เลือกที่จะบันทึกเราขอแนะนำชื่อ picture.png สำหรับไฟล์ที่คุณบันทึกเป็น"

ในเบราว์เซอร์เหล่านั้นที่รู้จักinlineบางคนจะใช้มันเสมอในขณะที่คนอื่น ๆ จะใช้มันหากผู้ใช้เลือก "บันทึกลิงค์เป็น" แต่ไม่ใช่ถ้าพวกเขาเลือก "บันทึก" ในขณะที่ดู (หรืออย่างน้อย IE เคยเป็นเช่นนั้น อาจมีการเปลี่ยนแปลงบางปีที่ผ่านมา)


30
นี่เป็นคำตอบที่ดีและมันจะดีมากถ้าสิ่งต่าง ๆ ได้ผล แต่น่าเสียดายที่เบราว์เซอร์ส่วนใหญ่จะใช้งานไม่ได้ ตัวอย่างเช่น Google Chrome จะไม่เปิดหน้าต่าง "บันทึกไฟล์" ให้คุณถ้านี่เป็นการตอบกลับของคุณจากแบบฟอร์มโดยไม่คำนึงถึงการรวม "เนื้อหา - การจัดการ: สิ่งที่แนบมา" แม้จะมี "application / octet-stream" เป็นประเภทเนื้อหา . จากนั้นพวกเขาก็พิมพ์ข้อความแจ้งว่าคุณอาจถูกโจมตี ... ไม่มีทางที่จะให้ฉันบันทึกไฟล์ได้ คุณต้องกำหนดค่า xdg-open แม้ว่าคุณต้องการบันทึกไฟล์ ฉันเบื่อสิ่งนี้
dividebyzero

1
@dividebyzero ไม่ใช่ปัญหาที่ฉันเคยมีรวมถึงกับ Chrome มีอะไรผิดปกติในสิ่งที่คุณกำลังทำอยู่หรือไม่?
Jon Hanna

1
การอัปโหลดไฟล์ที่มีประเภทเริ่มต้นอาจไม่ถูกต้องและอาจเป็นผลมาจากการตรวจจับการโจมตีบางครั้งแทนที่จะล้มลงเพื่อให้เนื้อหาไฟล์พร้อมใช้งาน
Jon Hanna

7
@Wilt ในกรณีที่ลูกค้าต้องการที่จะบันทึกมันแล้วมันไม่ได้ว่าสิ่งที่ส่วนหัวจะถูกส่ง (คุณสามารถ "บันทึก" หรือ "Save Link As" ในสิ่งที่อยู่ในเบราว์เซอร์ของคุณ) เป็นส่วนหัวที่มีข้อมูลไม่กฎดังนั้นattachmentอาจจะ ถือว่า "ดีที่สุดที่จะไม่แสดงสิ่งนี้ด้วยตัวคุณเอง" ในขณะinlineที่ "ควรแสดงด้วยตัวคุณเองหากทำได้" เบราว์เซอร์ส่วนใหญ่จะใช้ค่าชื่อไฟล์เป็นชื่อที่แนะนำของไฟล์ แต่ผู้ใช้สามารถแทนที่ได้เสมอ
Jon Hanna

1
@Tresdin ขอบคุณ ฉันค่อนข้างไม่พูดเลยว่ามันได้รับความนิยมมากเมื่อเทียบกับคนอื่น ๆ ของฉันฉันจะคิดว่าดีกว่านี้ แต่ฉันคิดว่ามันน่าจะเป็นจุดตอบรับปัญหาของผู้คน
Jon Hanna
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.