2011-12-12 14 views
13

mio attuale metodo è questo:In Node.js, dato un URL, come posso verificare se è un jpg/png/gif?

var request = require('request'); 
var mime = require('mime'); 
var fs = require('fs'); 
var uri = 'http://www.sweetslyrics.com/images/img_gal/25646_christina-perri-213968.jpg'; 
request({ 
     'method':'GET', 
     'uri': uri 
},function(err, response,body){ 
    var tmp_path = '/tmp/123456'; 
    fs.writeFile(tmp_path, body, function(err) { 
     console.log(mime.lookup(tmp_path)); //application/octet-stream ????? 
    }); 
}); 

L'immagine è ovviamente una foto, ma node-mime dice che è application/octet-stream. Perché?

Nota: - Non voglio fare affidamento sul tipo di contenuto delle intestazioni di risposta, perché in base alla mia esperienza, a volte tali intestazioni di risposta sono impostate in modo errato ... e non determinano il vero tipo di file. (questo è il motivo per cui l'ho salvato su un file e quindi ho determinato il nodo per me!)

Desidero sapere il modo migliore per determinare se un file è un'immagine, con 0 margine di errore.

Modifica: ho appena realizzato che node-mime non è "magico". Esso controlla solo per l'estensione :(...

Edit2: Ho trovato questo: https://github.com/SaltwaterC/mime-magic

+2

cosa c'è di sbagliato con il controllo gli ultimi tre caratteri del uri? – Raynos

+0

nota che se stai andando a recuperare il file per controllarlo ma non memorizzarlo, potrebbe essere meglio usare una richiesta di intervallo per i primi kilobyte piuttosto che recuperare l'intero file. –

risposta

29

Basta leggere i primi byte dello stream e controllarlo per il cosiddetto "numero magico"

I numeri magici sono i primi bit di un file che identificano univocamente il tipo di file .

Per esempio:
file di -Ogni JPEG inizia con ff d8 (hex).
-Ogni file png inizia con un 89 50 4e 47.
-Vi è un tavolo pieno di numeri magici here

In questo modo, anche se si dispone di un file senza estensione è ancora possibile rilevare il tipo.
Spero che questo aiuti.

+0

Esiste un modulo node-js che esegue questa operazione? – TIMEX

+0

@TIMEX Non ho sentito parlare di alcuna libreria per farlo, ma non ci vorranno più di dieci righe di codice per implementare tale funzionalità. Per ottenere il numero magico dal buffer basta usare 'buffer.toString ('hex', 0,4);'. Per un file jpg questa funzione restituirà 'ffd8ffe0'. Ora dovresti solo confrontare questa stringa con la tabella che ho specificato nella risposta per ottenere l'estensione e il tipo mime. – rcode

+0

c'è imagemagick per nodejs. lì puoi controllare il formato dell'immagine. maggiori informazioni su http://aheckmann.github.io/gm/docs.html – ufk

3

Ci sono due moduli che possono aiutare a raggiungere questo obiettivo:

https://github.com/SaltwaterC/mime-magic

https://github.com/bentomas/node-mime

+1

Il primo utilizza l'utilità della riga di comando "file" sui sistemi operativi * nix creando un sottoprocesso per ogni query, il secondo utilizza e il dizionario extension-mime – clyfe

+0

C'è un terzo modulo, considerando che si tratta solo di immagini: https://github.com/rsms/node-imagemagick – seppo0010

1

Nel frattempo, da quando è stata posta questa domanda, la magia mimica non è stata supportata e il suo autore raccomanda l'uso di mmmagic. Non so cosa sia successo a node-mime, il link sopra è un 404. Ho trovato il seguente articolo che tratta anche l'argomento: https://nodejsmodules.org/tags/mime

6

Questo codice mostra una soluzione di lavoro per l'approccio ai numeri magici (riassunto di le risposte e le informazioni esistenti su https://github.com/request/request).

var request = require('request'); 
var url = "http://www.somedomain.com/somepicture.jpg"; 
var magic = { 
    jpg: 'ffd8ffe0', 
    png: '89504e47', 
    gif: '47494638' 
}; 
var options = { 
    method: 'GET', 
    url: url, 
    encoding: null // keeps the body as buffer 
}; 

request(options, function (err, response, body) { 
    if(!err && response.statusCode == 200){ 
     var magigNumberInBody = body.toString('hex',0,4); 
     if (magigNumberInBody == magic.jpg || 
      magigNumberInBody == magic.png || 
      magigNumberInBody == magic.gif) { 

      // do something 

     } 
    } 
}); 
+0

Potresti per favore elaborare più la tua risposta aggiungendo un po 'più di descrizione della soluzione che fornisci? – abarisone

0

ho sviluppato questo codice e ho test e il lavoro per me si può utilizzare

var express = require('express') 
var app = express() 
var http = require('http').Server(app).listen(80) 
var upload = require('express-fileupload') 
app.use(upload()) 
     app.get("/",(req,res)=>{ 
      res.sendFile(__dirname+"/file.html") 
     }) 
app.post('/',(req,res)=>{ 
     var options = { 
      method: 'GET', 
      url: req.files.filename, 
      encoding: null 
     } 
     if (req.files) { 
     if (req.files.filename.data.toString('hex',0,4) == '89504e47' || req.files.filename.data.toString('hex',0,4) == 'ffd8ffe0' || req.files.filename.data.toString('hex',0,4) == '47494638') { 
      var file = req.files.filename 
      filename = file.name 
      file.mv('./upload/'+filename,(err)=>{ 
       if (err) { 
        console.log('small err') 
       } else { 
       res.send('DONE') 
       } 
      }) 
     } else { 
      console.log('it not an image') 
     } 
} 
}) 
Problemi correlati