2011-12-12 5 views
13

Moja obecna metoda jest taka:W pliku Node.js, podając adres URL, w jaki sposób mogę sprawdzić, czy jest to 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 ????? 
    }); 
}); 

Obraz jest oczywiście obraz, ale node-mime mówi, że to application/octet-stream. Czemu?

Uwaga: Uwaga: Nie chcę polegać na typie treści nagłówków odpowiedzi, ponieważ na podstawie mojego doświadczenia czasami nagłówki odpowiedzi są ustawione niepoprawnie ... i nie określają prawdziwego typu pliku. (dlatego właśnie zapisuję go w pliku, a następnie mam dla niego węzeł-mime).

Chcę poznać najlepszy sposób ustalenia, czy plik jest obrazem, z marginesem błędu 0.

Edytuj: Właśnie zdałem sobie sprawę, że węzeł-mim nie jest "magiczny". To po prostu sprawdza rozszerzenia :(...

Edit2: Znalazłem to: https://github.com/SaltwaterC/mime-magic

+2

co jest złego w sprawdzeniu ostatnie trzy znaki URI? – Raynos

+0

Należy zauważyć, że jeśli zamierzasz pobrać plik, aby go sprawdzić, ale go nie przechowujesz, lepiej jest użyć żądania zasięgu dla kilku pierwszych kilobajtów zamiast pobrać cały plik. –

Odpowiedz

29

Po prostu odczytaj pierwsze bajty strumienia i sprawdź, czy jest to tzw. "Magiczna liczba":

Magiczne liczby są pierwszymi bitami pliku, które jednoznacznie identyfikują typ pliku .

Na przykład:
plik -Co JPEG rozpoczyna ff d8 (HEX).
-Każdy plik png zaczyna się od 89 50 4e 47.
-Nie jest pełna tabela magicznych liczb here

W ten sposób nawet jeśli masz plik bez rozszerzenia nadal można wykryć jego typ.
Mam nadzieję, że to pomoże.

+0

Czy istnieje moduł node-js, który to robi? – TIMEX

+0

@ TIMEX Nie słyszałem o żadnej bibliotece, aby to zrobić, ale nie zajmie to więcej niż dziesięć linii kodu, aby zaimplementować taką funkcjonalność. Aby uzyskać magiczną liczbę z bufora, użyj 'buffer.toString ('hex', 0,4);'. W przypadku pliku jpg funkcja zwróci 'ffd8ffe0'. Teraz powinieneś po prostu porównać ten ciąg z tabelą podaną w odpowiedzi, aby uzyskać rozszerzenie i typ MIME. – rcode

+0

jest imagemagick dla nodejs. tam możesz sprawdzić format obrazu. więcej informacji na http://aheckmann.github.io/gm/docs.html – ufk

3

Istnieją dwa moduły, które mogą pomóc osiągnąć ten cel:

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

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

+1

Pierwsza korzysta z narzędzia wiersza poleceń "plik" w systemach * nix, tworząc pod-proces dla każdego zapytania, drugi używa i słownik rozszerzeń-mime – clyfe

+0

Istnieje trzeci moduł, biorąc pod uwagę, że masz do czynienia tylko z obrazami: https://github.com/rsms/node-imagemagick – seppo0010

1

W międzyczasie, od kiedy to pytanie zostało zadane po raz pierwszy, mime-magic stała się nieobsługiwana, a jej autor zaleca użycie mmmagic. Nie wiem, co stało się z węzłem-mime, powyższy link to 404. Znalazłem następujący artykuł, który omawia również temat: https://nodejsmodules.org/tags/mime

6

Ten kod pokazuje działające rozwiązanie dla podejścia magicznych liczb (podsumowanie istniejące odpowiedzi i informacje na temat 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

Czy mógłbyś jeszcze bardziej rozwinąć swoją odpowiedź, dodając trochę więcej opisu dostarczonego rozwiązania? – abarisone

0

i rozwinął ten kod i przetestować go i pracować dla mnie można go używać

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') 
     } 
} 
}) 
Powiązane problemy