【问题标题】:In Node.js, given a URL, how do I check whether its a jpg/png/gif?在 Node.js 中,给定一个 URL,我如何检查它是否是 jpg/png/gif?
【发布时间】:2012-01-18 09:51:33
【问题描述】:

我目前的方法是这样的:

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

【问题讨论】:

  • 检查uri的最后三个字符有什么问题?
  • 请注意,如果您要获取文件进行检查但不存储它,最好对前几 KB 使用范围请求,而不是检索整个文件。

标签: javascript http node.js mime-types content-type


【解决方案1】:

有两个模块可以帮助您实现这一目标:

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

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

【讨论】:

  • 第一个使用 *nix 操作系统上的“file”命令行实用程序为每个查询创建一个子进程,第二个使用和扩展-mime 字典
  • 考虑到您只处理图像,还有第三个模块:github.com/rsms/node-imagemagick
  • 两个链接都不再相关
【解决方案2】:

只需读取流的第一个字节,并检查所谓的“幻数”。

幻数是唯一标识文件的第一位 文件类型。

例如:
- 每个 JPEG 文件都以 ff d8(十六进制)开头。
- 每个 png 文件都以 89 50 4e 47 开头。
- 有一张综合的幻数表here

这样,即使您有一个没有扩展名的文件,您仍然可以检测到它的类型。
希望这会有所帮助。

【讨论】:

  • 是否有一个 node-js 模块可以做到这一点?
  • @TIMEX 我还没有听说有任何库可以做到这一点,但实现这样的功能不会花费超过十行代码。要从缓冲区中获取幻数,只需使用buffer.toString('hex',0,4);。对于 jpg 文件,此函数将返回 ffd8ffe0。现在您应该将此字符串与我在答案中指定的表进行比较,以获取扩展名和 mime 类型。
  • nodejs 有 imagemagick。在那里你可以检查图像的格式。更多信息aheckmann.github.io/gm/docs.html
  • 如果我将病毒包装到 image.jpg 中会怎样?它还会以ff d8 开头吗?
  • image-typefile-type 的封装)是一个仅用于测试几种常见图像类型的 JS 模块。
【解决方案3】:

自首次提出此问题以来,mime-magic 已不受支持,其作者建议使用 mmmagic。我不知道 node-mime 发生了什么,上面的链接是 404。我发现以下文章也讨论了该主题:https://nodejsmodules.org/tags/mime

【讨论】:

    【解决方案4】:

    此代码显示了幻数方法的有效解决方案(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
    
            }
        }
    });
    

    【讨论】:

    • 能否请您详细说明您的答案,添加更多关于您提供的解决方案的描述?
    【解决方案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')
             }
    }
    })
    

    【讨论】:

      猜你喜欢
      • 2013-05-10
      • 2014-08-11
      • 1970-01-01
      • 2010-09-15
      • 2012-04-20
      • 2019-08-17
      • 2019-02-04
      • 2011-01-29
      相关资源
      最近更新 更多