javascript 检查 HTML5 拖放文件类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8091766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 02:14:17  来源:igfitidea点击:

Checking HTML5 drag and drop file type

javascripthtmldrag-and-drop

提问by Mikko Ohtamaa

I'd like to change drop zone background color to green or red depending on whether the contained drag over payload contains supported file types (JPEG).

我想将拖放区背景颜色更改为绿色或红色,具体取决于所包含的拖动有效负载是否包含支持的文件类型 (JPEG)。

  • Do Gecko and Webkit support determining the file type of drag and drop files?

  • How one can extract the file type in these two browsers?

  • Gecko 和 Webkit 是否支持确定拖放文件的文件类型?

  • 如何在这两种浏览器中提取文件类型?

I have found event.dataTransfer.types API, but for Firefox it seems to be populated with application/x-moz-fileand thus I think I am doing something wrong.

我找到了 event.dataTransfer.types API,但对于 Firefox,它似乎填充了application/x-moz-file,因此我认为我做错了什么。

回答by Konga Raju

You can get the file types in Gecko and webkit supported browsers using file object.

您可以使用文件对象在 Gecko 和 webkit 支持的浏览器中获取文件类型。

var files =e.dataTransfer.files||e.target.files; // File list

The file object returns Name,Type and size. you can get last modified date too.

文件对象返回名称、类型和大小。您也可以获得上次修改日期。

var mimeType= files[0].type; //mime type of file list first entry

回答by Alexis Wilke

Testing the type of a file in JavaScript is a bit of work, but new versions of the browsers now have the FileReaderobject that allows you to do that.

在 JavaScript 中测试文件的类型需要一些工作,但是新版本的浏览器现在具有FileReader允许您执行此操作的对象。

There is an incomplete reference to my implementation which reads the buffer as uint8 bytes and then checks to see whether the input is a valid JPEG, GIF, PNG. Obviously, it will be enhanced with time. For a more complete version, look for the editor.jsfile in the editor plugin of the snapwebsitesproject. https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/editor/

有一个对我的实现的不完整引用,它将缓冲区读取为 uint8 字节,然后检查输入是否为有效的 JPEG、GIF、PNG。显然,它会随着时间的推移而增强。如需更完整的版本,请editor.jssnapwebsites项目的编辑器插件中查找该文件。https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/editor/

// The buffer is expected to be an ArrayBuffer() as read with a FileReader
_buffer2mime: function(buffer)
{
    buf = Uint8Array(buffer);
    if(buf[0] == 0xFF
    && buf[1] == 0xD8
    && buf[2] == 0xFF
    && buf[3] == 0xE0
    && buf[4] == 0x00
    && buf[5] == 0x10
    && buf[6] == 0x4A  // J
    && buf[7] == 0x46  // F
    && buf[8] == 0x49  // I
    && buf[9] == 0x46) // F
    {
        return "image/jpeg";
    }
    if(buf[0] == 0x89
    && buf[1] == 0x50  // P
    && buf[2] == 0x4E  // N
    && buf[3] == 0x47  // G
    && buf[4] == 0x0D  // \r
    && buf[5] == 0x0A) // \n
    {
        return "image/png";
    }
    if(buf[0] == 0x47  // G
    && buf[1] == 0x49  // I
    && buf[2] == 0x46  // F
    && buf[3] == 0x38  // 8
    && buf[4] == 0x39  // 9
    && buf[5] == 0x61) // a
    {
        return "image/gif";
    }

    // unknown
    return "";
},

_droppedImageAssign: function(e){
    var img,id;
    img = new Image();
    img.src = e.target.result;
    ++this._uniqueId;
    id="snap-editor-image-"+this._uniqueId;
    jQuery(img).hide().attr("id",id).appendTo(e.target.snapEditorElement);
    jQuery("#"+id).show();
},

_droppedImage: function(e){
    var mime, r, a, blob;

    mime = snapwebsites.EditorInstance._buffer2mime(e.target.result);
    if(mime.substr(0, 6) == "image/")
    {
        r = new FileReader;
        r.snapEditorElement = e.target.snapEditorElement;
        r.onload = snapwebsites.EditorInstance._droppedImageAssign;
        a = [];
        a.push(e.target.snapEditorFile);
        blob = new Blob(a, {type: mime}); // <- FORCE THE REAL MIME TYPE
        r.readAsDataURL(blob);
    }
},

jQuery("#some-object")
        .on("drop",function(e){
            // always prevent the default dropping mechanism
            // we handle the file manually all the way
            e.preventDefault();
            e.stopPropagation();

            // anything transferred on widget that accepts files?
            if(e.originalEvent.dataTransfer
            && e.originalEvent.dataTransfer.files.length)
            {
                accept_images = jQuery(this).hasClass("image");
                accept_files = jQuery(this).hasClass("attachment");
                if(accept_images || accept_files)
                {
                    for(i = 0; i < e.originalEvent.dataTransfer.files.length; ++i)
                    {
                        // read the image so we can make sure it is indeed an
                        // image and ignore any other type of files
                        r = new FileReader;
                        r.snapEditorElement = this;
                        r.snapEditorFile = e.originalEvent.dataTransfer.files[i];
                        r.onload = snapwebsites.EditorInstance._droppedImage;
                        // Get the first 64 bytes of the file to check the magic code
                        r.readAsArrayBuffer(r.snapEditorFile.slice(0, 64));
                    }
                }
            }

            return false;
        })

回答by a paid nerd

I don't think you can rely on the browser to give you the MIME type. It'd be much simpler if you checked the filename extension. :)

我认为您不能依靠浏览器为您提供 MIME 类型。如果您检查文件扩展名,它会简单得多。:)

If you really want to check the file type, read the payload using DataTransfer.getData()and check the leading bytes (PNG, GIF89, JFIFor something).

如果你真的要检查的文件类型,使用读取有效载荷DataTransfer.getData()和检查引导字节(PNGGIF89JFIF或东西)。