ประเภท mime ของไฟล์ที่อัพโหลดถูกกำหนดโดยเบราว์เซอร์อย่างไร?


87

ฉันมีแอปพลิเคชันเว็บที่ผู้ใช้ต้องการอัปโหลดไฟล์. zip บนฝั่งเซิร์ฟเวอร์, ฉันกำลังตรวจสอบประเภท MIME ของไฟล์ที่อัปโหลดเพื่อให้แน่ใจว่ามันเป็นหรือapplication/x-zip-compressedapplication/zip

สิ่งนี้ใช้ได้ดีสำหรับฉันใน Firefox และ IE อย่างไรก็ตามเมื่อเพื่อนร่วมงานทำการทดสอบมันล้มเหลวสำหรับเขาบน Firefox (ประเภท mime ที่ส่งมาคือ " application/octet-stream") แต่ทำงานบน Internet Explorer การตั้งค่าของเราดูเหมือนจะเหมือนกัน: IE8, FF 3.5.1 เมื่อปิดใช้งานส่วนเสริมทั้งหมด, Win XP SP3, WinRAR ติดตั้งเป็นตัวจัดการไฟล์. zip ดั้งเดิม (ไม่แน่ใจว่าเกี่ยวข้องหรือไม่)

คำถามของฉันคือ: เบราว์เซอร์จะกำหนดประเภทละครใบ้ที่จะส่งได้อย่างไร?

โปรดทราบ: ฉันทราบว่าเบราว์เซอร์ส่งประเภทละครใบ้จึงไม่น่าเชื่อถือ ฉันแค่ตรวจสอบตามความสะดวก - ส่วนใหญ่จะให้ข้อความแสดงข้อผิดพลาดที่เป็นมิตรมากกว่าข้อความที่คุณได้รับโดยพยายามเปิดไฟล์ที่ไม่ใช่ zip เป็นไฟล์ zip และเพื่อหลีกเลี่ยงการโหลดไลบรารีไฟล์ zip (ซึ่งน่าจะหนัก)


application / octet-stream กำหนดไฟล์ไบนารี คุณควรจะได้รับนามสกุลของไฟล์เพื่อดูว่าเป็นไฟล์ zip หรือไม่ เพื่อชี้แจงว่าสิ่งนี้ได้ผลสำหรับคุณใน FF แต่ไม่ใช่เพื่อนร่วมงานของคุณหรือไม่?
Kevin Crowell

ใช่มันใช้ได้สำหรับฉันในเบราว์เซอร์ทั้งสอง
Kip

ดูที่input/@formenctypeหรือform/@enctypeคุณลักษณะ
tuxSlayer

คำตอบ:


72

โครเมียม

Chrome (เวอร์ชัน 38 ขณะเขียน)มี 3 วิธีในการกำหนดประเภท MIME และทำตามลำดับที่กำหนด ข้อมูลด้านล่างเป็นจากแฟ้มวิธีsrc/net/base/mime_util.ccMimeUtil::GetMimeTypeFromExtensionHelper

// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type.  That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.

รายการฮาร์ดโค้ดมาก่อนหน้านี้เล็กน้อยในไฟล์: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 ( kPrimaryMappingsและkSecondaryMappings)

ตัวอย่าง: เมื่ออัปโหลดไฟล์ CSV จากระบบ Windows ที่ติดตั้ง Microsoft Excel Chrome จะรายงานเป็นapplication/vnd.ms-excelไฟล์. เนื่องจาก.csvไม่ได้ระบุไว้ในรายการฮาร์ดโค้ดรายการแรกดังนั้นเบราว์เซอร์จึงกลับไปที่รีจิสทรีของระบบ HKEY_CLASSES_ROOT\.csvมีค่าชื่อที่ถูกตั้งContent Typeapplication/vnd.ms-excel

Internet Explorer

application/vnd.ms-excelอีกครั้งโดยใช้ตัวอย่างเดียวกันเบราว์เซอร์จะรายงาน ฉันคิดว่ามันสมเหตุสมผลที่จะถือว่า Internet Explorer (เวอร์ชัน 11 ในขณะที่เขียน)ใช้รีจิสทรี อาจใช้ประโยชน์จากรายการฮาร์ดโค้ดเช่น Chrome และ Firefox แต่ลักษณะของแหล่งที่มาปิดทำให้ยากต่อการตรวจสอบ

Firefox

ตามที่ระบุไว้ในโค้ด Chrome Firefox (เวอร์ชัน 32 ขณะเขียน)ทำงานในลักษณะเดียวกัน ตัวอย่างข้อมูลจากไฟล์uriloader\exthandler\nsExternalHelperAppService.cppวิธีการnsExternalHelperAppService::GetTypeFromExtension

// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category

รายการฮาร์ดโค้ดมาก่อนหน้านี้ในแฟ้มบรรทัดที่ไหนสักแห่งใกล้ 441 คุณกำลังมองหาและdefaultMimeEntriesextraMimeEntries

ด้วยโปรไฟล์ปัจจุบันของฉันเบราว์เซอร์จะรายงานtext/csvเนื่องจากมีรายการอยู่ในmimeTypes.rdf(รายการที่ 2 ในรายการด้านบน) ด้วยโปรไฟล์ใหม่ซึ่งไม่มีรายการนี้เบราว์เซอร์จะรายงานapplication/vnd.ms-excel(รายการที่ 3 ในรายการ)

สรุป

รายการฮาร์ดโค้ดในเบราว์เซอร์ค่อนข้าง จำกัด บ่อยครั้งประเภท MIME ที่เบราว์เซอร์ส่งจะเป็นประเภทที่ระบบปฏิบัติการรายงาน และนี่คือเหตุผลว่าทำไมตามที่ระบุไว้ในคำถามประเภท MIME ที่เบราว์เซอร์รายงานไม่น่าเชื่อถือ


1
ขอบคุณ! คุณมีลิงก์ไปยังรายการฮาร์ดโค้ดในแหล่งที่มาของ Chrome หรือไม่
กีบ

@Kip ใช่ฉันได้เพิ่มลิงค์แล้ว Firefox ดูเหมือนจะไม่มีเบราว์เซอร์ซอร์สโค้ดออนไลน์ (อย่างเป็นทางการ) ฉันต้องดาวน์โหลดจากเซิร์ฟเวอร์ FTP
user247702

การมี MIME เป็น ms-excel สำหรับ CSV นั้นน่ารำคาญสงสัยว่าเหตุใดจึงไม่อยู่ในรายการฮาร์ดโค้ด
Kris

คงจะดีไม่น้อยหากทราบว่ามีการอัปเดตการตรวจจับประเภทละครใบ้ตั้งแต่ปี 2014 หรือไม่
Vitaly Isaev

1
@VitalyIsaev ดูคร่าวๆที่โค้ด Chrome แสดงว่าสิ่งนี้ไม่ได้เปลี่ยนแปลงตั้งแต่ปี 2014
user247702

12

Kip ฉันใช้เวลาอ่าน RFCs, MSDN และ MDN นี่คือสิ่งที่ฉันเข้าใจ เมื่อเบราว์เซอร์พบไฟล์สำหรับอัปโหลดเบราว์เซอร์จะดูที่บัฟเฟอร์แรกของข้อมูลที่ได้รับจากนั้นจึงทำการทดสอบ การทดสอบเหล่านี้พยายามตรวจสอบว่าไฟล์เป็นประเภทละครใบ้ที่รู้จักหรือไม่และหากรู้จักประเภทละครใบ้ก็จะทดสอบเพิ่มเติมว่าประเภทละครใบ้ที่รู้จักและดำเนินการตามนั้น ฉันคิดว่า IE พยายามทำสิ่งนี้ก่อนแทนที่จะกำหนดประเภทไฟล์จากนามสกุลเท่านั้น หน้านี้จะอธิบายถึงนี้สำหรับ IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx สำหรับ firefox สิ่งที่ฉันเข้าใจก็คือมันพยายามอ่านข้อมูลไฟล์จากระบบไฟล์หรือรายการไดเร็กทอรีจากนั้นกำหนดประเภทไฟล์ นี่คือลิงค์สำหรับ FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. ฉันยังคงต้องการข้อมูลที่เชื่อถือได้เพิ่มเติมเกี่ยวกับเรื่องนี้


8

นี่อาจเป็นระบบปฏิบัติการและอาจขึ้นอยู่กับเบราว์เซอร์ แต่สำหรับ Windows คุณสามารถค้นหาประเภท MIME สำหรับนามสกุลไฟล์ที่กำหนดได้โดยดูในรีจิสทรีภายใต้ HKCR:

ตัวอย่างเช่น:

HKEY_CLASSES_ROOT.zip - ContentType

หากต้องการเปลี่ยนจาก MIME เป็นนามสกุลไฟล์คุณสามารถดูที่ปุ่มด้านล่าง

HKEY_CLASSES_ROOT \ Mime \ Database \ Content Type

เพื่อรับส่วนขยายเริ่มต้นสำหรับประเภท MIME ที่เฉพาะเจาะจง


ขอบคุณ. น่าเสียดายสำหรับทั้งฉันและเพื่อนร่วมงานสิ่งนี้ดูเหมือนจะถูกต้องในรีจิสทรีของเรา ฉันเดาว่านั่นเป็นเหตุผลว่าทำไมมันถึงทำงานใน IE สำหรับเขา แต่ FF ก็ทำให้มันแตกต่างออกไป ... โอ้ดี :(
กีบ

5

แม้ว่านี่จะไม่ใช่คำตอบสำหรับคำถามของคุณ แต่ก็ช่วยแก้ปัญหาที่คุณพยายามแก้ได้ YMMV.

อย่างที่คุณเขียนประเภท mime ไม่น่าเชื่อถือเนื่องจากเบราว์เซอร์แต่ละตัวมีวิธีพิจารณา อย่างไรก็ตามเบราว์เซอร์จะส่งชื่อเดิม (รวมถึงนามสกุล) ของไฟล์ ดังนั้นวิธีที่ดีที่สุดในการจัดการกับปัญหาคือตรวจสอบนามสกุลของไฟล์แทนประเภท MIME

หากคุณยังต้องการประเภท mime คุณสามารถใช้ mime.types ของ apache ของคุณเองเพื่อกำหนดประเภทเซิร์ฟเวอร์


1
สนใจที่จะทำอย่างละเอียด? จากประสบการณ์ของฉันเบราว์เซอร์จะส่งชื่อไฟล์ต้นฉบับที่ถูกต้องเสมอ (พร้อมนามสกุล) ในขณะที่ประเภท MIME แตกต่างกันมาก ใช่ฉันจะบอกว่ามันน่าเชื่อถือกว่ามาก
johndodo

แก้ไข. ฉันตั้งใจจะบอกว่าผู้ใช้สามารถใส่ส่วนขยายใดก็ได้โดยไม่คำนึงถึงประเภทที่แท้จริงดังนั้นจึงไม่ควรเชื่อถือ
Djizeus

นั่นเป็นความจริง แต่ไม่สำคัญว่าคุณจะใช้นามสกุลหรือประเภท MIME คุณไม่ควรไว้วางใจอินพุตที่ผู้ใช้ให้มา แต่ OP ระบุชัดเจนว่าเขาตระหนักถึงปัญหานี้ดังนั้นนี่จึงไม่ใช่ส่วนหนึ่งของคำถามนี้ Btw ฉันจะขอบคุณถ้าคุณลบ downvote (ฉันคิดว่ามันมาจากคุณ)
johndodo

คุณพูดถูกไม่ได้ใส่ใจกับคำถามที่ไม่ดีของฉัน ฉันสามารถยกเลิกการโหวตได้ แต่คุณจะต้องแก้ไขคำตอบสำหรับสิ่งนั้น (บังคับใช้โดยระบบ) ...
Djizeus

ใช่ฉันเห็นด้วยกับ johndodo ตามที่ Stijn อธิบายไว้ในคำตอบข้างต้น Chrome และ Firefox จะตรวจสอบส่วนขยายก่อน พวกเขากำลังทำสิ่งเดียวกันในที่สุด
Jenix

0

ฉันเห็นด้วยกับ johndodo มีตัวแปรมากมายที่ทำให้ประเภทละครใบ้ที่ส่งจากเบราว์เซอร์ไม่น่าเชื่อถือ ฉันจะไม่รวมประเภทย่อยที่ได้รับและมุ่งเน้นไปที่ประเภทเช่น 'แอปพลิเคชัน' หากแอปของคุณใช้ php คุณสามารถทำได้อย่างง่ายดายโดยใช้ฟังก์ชันระเบิด () นอกจากนี้เพียงตรวจสอบนามสกุลไฟล์เพื่อให้แน่ใจว่าเป็น. zip หรือการบีบอัดอื่น ๆ ที่คุณกำลังมองหา!


0

อ้างอิงจากrfc1867 - การอัปโหลดไฟล์แบบฟอร์มใน HTML :

แต่ละส่วนควรติดป้ายกำกับด้วยประเภทเนื้อหาที่เหมาะสมหากรู้จักประเภทสื่อ (เช่นอนุมานจากนามสกุลไฟล์หรือข้อมูลการพิมพ์ของระบบปฏิบัติการ) หรือเป็นแอปพลิเคชัน / ออคเต็ตสตรีม

ดังนั้นความเข้าใจของฉันก็application/octet-streamเหมือนกับblanket catch-allตัวระบุหากไม่สามารถอนุมานประเภทได้


ใช่ฉันเข้าใจทั้งหมดนี้ คำถามคือเบราว์เซอร์อนุมานได้อย่างไร
Kip

นั่นก็น่ารู้ใช่มั้ย? ถ้าเป็นที่รับทั้งหมดแล้วอีกวิธีหนึ่งที่จะไว้วางใจเบราว์เซอร์ถ้ามันได้รับสามารถที่จะทำให้การคาดเดาและทำแบบทดสอบด้านเซิร์ฟเวอร์ของคุณเองถ้าคุณได้รับapplication/octet-stream application/octet-stream
MikeBeaton
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.