2011-12-12 49 views
13

我現在的方法是這樣的:在Node.js中,如果給出一個URL,我該如何檢查它是否爲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 ????? 
    }); 
}); 

的圖像顯然是一個圖片,但node-mime說,這是application/octet-stream。爲什麼?

注: - 我不想依靠響應頭內容類型,因爲根據我的經驗,有時那些響應頭設置不正確......他們並不確定真正的文件類型。 (這就是爲什麼我把它保存到一個文件,然後讓node-mime爲我確定!)

我想知道確定文件是否爲圖像的最佳方式,並且有0的誤差範圍。

編輯:我只是意識到,節點模仿不是「魔術」。它只是檢查擴展:(...

EDIT2:我發現這一點:https://github.com/SaltwaterC/mime-magic

+2

有什麼錯檢查URI的最後三個字符? – Raynos

+0

請注意,如果您要獲取文件以進行檢查但不存儲該文件,則可能會更好地在前幾千字節範圍內使用範圍請求,而不是檢索整個文件。 –

回答

29

只讀流的第一個字節,並檢查它的所謂「幻數」。

幻數是唯一標識文件類型的文件的第一位。

例如:
-Every JPEG文件以ff d8(十六進制)。
- 每個png文件都以89 50 4e 47開頭。
- 有一個完整的幻數表格here

這種方式即使你有一個沒有擴展名的文件,你仍然可以檢測到它的類型。
希望這會有所幫助。

+0

有沒有一個node-js模塊來做到這一點? – TIMEX

+0

@TIMEX我還沒有聽說過任何庫可以做到這一點,但它不會花費超過十行代碼來實現這樣的功能。要從緩衝區中獲得幻數,只需使用'buffer.toString('hex',0,4);'。對於jpg文件,此函數將返回'ffd8ffe0'。現在,您應該將該字符串與我在答案中指定的表進行比較以獲取擴展名和MIME類型。 – rcode

+0

有nodejs的imagemagick。在那裏你可以檢查圖像的格式。更多信息在http://aheckmann.github.io/gm/docs.html – ufk

1

在第一次詢問這個問題之後的時間裏,mime-magic已經不被支持,它的作者建議使用mmmagic。我不知道node-mime發生了什麼,上面的鏈接是404.我發現下面的文章討論了這個主題:https://nodejsmodules.org/tags/mime

6

這段代碼顯示了神奇數字方法的工作解決方案現有答案和有關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

您能否詳細說明您的答案,並增加關於您提供的解決方案的更多描述? – abarisone

0

我developped此代碼,我測試它,它爲我工作,你可以用它

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') 
     } 
} 
}) 
相關問題