Подтвердить что ты не робот

В 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 пределом ошибки.

Изменить: я только понял, что node -mime не является "магии". Он просто проверяет расширение: (...

Edit2: Я нашел это: https://github.com/SaltwaterC/mime-magic

4b9b3361

Ответ 1

Просто прочитайте первые байты потока и проверьте его на наличие так называемого "магического числа".

Магические числа - это первые биты файла, которые однозначно определяют тип файла.

Например:
-Every Файл JPEG начинается с ff d8 (hex).
-Every png файл начинается с 89 50 4e 47.
-There представляет собой полную таблицу магических чисел здесь

Таким образом, даже если у вас есть файл без расширения, вы все равно можете определить его тип.
Надеюсь это поможет.

Ответ 2

Этот код показывает рабочее решение для подхода магических чисел (сводка существующих ответов и информация о 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

        }
    }
});

Ответ 4

В промежуток времени, когда этот вопрос был задан впервые, mime-magic становится неподдерживаемым, и его автор рекомендует использовать mmmagic. Я не знаю, что случилось с node -mime, ссылка выше 404. Я нашел следующую статью, в которой также обсуждается тема: https://nodejsmodules.org/tags/mime

Ответ 5

Я разработал этот код, и я тестирую его, и он работает для меня, вы можете его использовать.

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')
         }
}
})