Domanda

Ho un'app Web in cui l'utente deve caricare un file .zip. Sul lato server, sto controllando il tipo mime del file caricato, per assicurarmi che sia application / x-zip-compressed o application / zip .

Questo ha funzionato bene per me su Firefox e IE. Tuttavia, quando un collega lo ha testato, non è riuscito per lui su Firefox (il tipo mime inviato era qualcosa come " application / octet-stream ") ma ha funzionato su Internet Explorer. Le nostre configurazioni sembrano identiche: IE8, FF 3.5.1 con tutti i componenti aggiuntivi disabilitati, Win XP SP3, WinRAR installato come gestore di file .zip nativo (non sono sicuro che sia pertinente).

Quindi la mia domanda è: In che modo il browser determina quale tipo di mime inviare?

Nota: so che il tipo mime viene inviato dal browser e, quindi, inaffidabile. Lo sto solo verificando per praticità, principalmente per dare un messaggio di errore più amichevole di quelli che ottieni provando ad aprire un file non zip come file zip ed evitare di caricare le librerie (presumibilmente pesanti) di file zip.

È stato utile?

Soluzione

Chrome

Chrome (versione 38 al momento della scrittura) ha 3 modi per determinare il tipo MIME e lo fa in un certo ordine. Lo snippet di seguito è dal file src / net / base / mime_util.cc , metodo MimeUtil :: 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.

Gli elenchi hardcoded sono presenti un po 'prima nel file: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 ( kPrimaryMappings e kSecondaryMappings ).

Un esempio: quando si carica un file CSV da un sistema Windows con Microsoft Excel installato, Chrome lo segnala come application / vnd.ms-excel . Questo perché .csv non è specificato nel primo elenco hardcoded, quindi il browser torna al registro di sistema. HKEY_CLASSES_ROOT \ .csv ha un valore denominato Tipo di contenuto impostato su application / vnd.ms-excel .

Internet Explorer

Sempre usando lo stesso esempio, il browser segnalerà application / vnd.ms-excel . Penso che sia ragionevole supporre che Internet Explorer (versione 11 al momento della scrittura) usi il registro. Probabilmente fa anche uso di un elenco hardcoded come Chrome e Firefox, ma la sua natura chiusa rende difficile la verifica.

Firefox

Come indicato nel codice Chrome, Firefox (versione 32 al momento della scrittura) funziona in modo simile. Snippet dal file uriloader \ exthandler \ nsExternalHelperAppService.cpp , metodo 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

Le liste hardcoded sono in precedenza nel file, da qualche parte vicino alla linea 441. Stai cercando defaultMimeEntries e extraMimeEntries .

Con il mio profilo attuale, il browser segnalerà text / csv perché è presente una voce in mimeTypes.rdf (elemento 2 nell'elenco sopra). Con un nuovo profilo, che non ha questa voce, il browser segnalerà application / vnd.ms-excel (elemento 3 nell'elenco).

Sommario

Gli elenchi hardcoded nei browser sono piuttosto limitati. Spesso, il tipo MIME inviato dal browser sarà quello segnalato dal sistema operativo. E questo è esattamente il motivo per cui, come indicato nella domanda, il tipo MIME segnalato dal browser non è affidabile.

Altri suggerimenti

Kip, ho passato un po 'di tempo a leggere RFC, MSDN e MDN. Ecco cosa potrei capire. Quando un browser rileva un file per il caricamento, esamina il primo buffer di dati che riceve e quindi esegue un test su di esso. Questi test tentano di determinare se il file è un tipo MIME noto o meno e, se noto, il tipo MIME lo testerà ulteriormente per il tipo MIME noto e agirà di conseguenza. Penso che IE cerchi di farlo prima piuttosto che determinare semplicemente il tipo di file dall'estensione. Questa pagina spiega questo per IE http: // msdn .microsoft.com / en-us / library / ms775147% 28v = vs.85% 29.aspx . Per Firefox, quello che ho potuto capire è che tenta di leggere le informazioni sui file dal filesystem o dalla voce della directory e quindi determina il tipo di file. Ecco un link per FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. Vorrei ancora avere informazioni più autorevoli su questo.

Probabilmente dipende dal sistema operativo e probabilmente dal browser, ma su Windows è possibile trovare il tipo MIME per una determinata estensione di file cercando nel registro sotto HKCR:

Ad esempio:

HKEY_CLASSES_ROOT.zip - ContentType

Per passare da MIME all'estensione di file, puoi guardare le chiavi in ??

HKEY_CLASSES_ROOT \ Mime \ Database \ Tipo di contenuto

Per ottenere l'estensione predefinita per un particolare tipo MIME.

Anche se questa non è una risposta alla tua domanda, risolve il problema che stai cercando di risolvere. YMMV.

Come hai scritto, il tipo mime non è affidabile in quanto ogni browser ha il suo modo di determinarlo. Tuttavia, i browser inviano il nome originale (inclusa l'estensione) del file. Quindi il modo migliore per affrontare il problema è ispezionare l'estensione del file anziché il tipo MIME.

Se hai ancora bisogno del tipo mime, puoi usare mime.types del tuo apache per determinarlo sul lato server.

Sono d'accordo con johndodo, ci sono così tante variabili che rendono i tipi mime inviati dai browser inaffidabili. Escluderei i sottotipi che vengono ricevuti e mi concentrerei solo sul tipo come "applicazione". se la tua app è basata su php, puoi farlo facilmente usando la funzione explode (). inoltre, controlla l'estensione del file per assicurarti che sia .zip o qualsiasi altra compressione che stai cercando!

Secondo rfc1867 - Caricamento di file basato su moduli in HTML :

  

Ogni parte deve essere etichettata con un tipo di contenuto appropriato se il   è noto il tipo di supporto (ad es. inferito dall'estensione del file o   informazioni sulla digitazione del sistema operativo) o come application / octet-stream.

Quindi la mia comprensione è che application / octet-stream è un po 'come un identificatore blanket catch-all se il tipo non può essere dedotto .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top