从剪贴板上传文件(仅限客户端)

时间:2014-03-21 14:04:04

标签: javascript

我正在维护一个现有的应用程序(无法更改服务器端代码,只能更改客户端js)并被要求添加从剪贴板上传文件的功能。
目前有一个标准的文件选择表格

<form id="file_form" name="file_form" enctype="multipart/form-data" method="post" action="/upload">
        <label for="selector">
            File Location
        </label>
        <input type="file" id="selector" name="selector" title="Choose file">
        <input type="submit" id="submit" value="ОК">
        <input type="button" id="cancel" onclick="cancel()" value="Cancel">
</form>

所以我需要的是一种用剪贴板填充input#selector文件的方法。我不需要进度条,预览,图像裁剪等......尽可能简单,但请记住我无法更改服务器上的任何内容。

是否有适用于Chrome,FF和IE的解决方案?

我搜索的大多数内容都是功能过多,需要大量外部js或服务器端代码更改,或者除了Chrome之外的任何其他内容都无法使用...

1 个答案:

答案 0 :(得分:0)

您可以参考此站点:https://www.pastefile.com

核心代码paste.js,例如

(function ($) {
    'use strict';

    var readImagesFromEditable = function (element, callback) {
        setTimeout(function () {
            $(element).find('img').each(function (i, img) {
                getImageData(img.src, callback);
            });
        }, 1);
    };

    var getImageData = function (src, callback) {
        var loader = new Image();

        loader.onload = function () {
            var canvas = document.createElement('canvas');
            canvas.width = loader.width;
            canvas.height = loader.height;

            var context = canvas.getContext('2d');
            context.drawImage(loader, 0, 0, canvas.width, canvas.height);

            try {
                var dataURL = canvas.toDataURL('image/png');
                if (dataURL) {
                    callback({
                        dataURL: dataURL
                    });
                }
            } catch (err) {}
        };

        loader.src = src;
    };

    $.paste = function () {

        var handler = function (e) {

            var pasteBoard = $(this);

            var trigger = function (event, data) {

                if (arguments.length > 1)
                    return pasteBoard.trigger(event, data);

                return function (data) {
                    return pasteBoard.trigger(event, data);
                };
            };

            var clipboardData, text;

            if (e.originalEvent) {
                clipboardData = e.originalEvent.clipboardData;

                if (clipboardData.items) {
                    var items = clipboardData.items;

                    // Copy-paste on OSX
                    if (items.length === 2) {

                        // If a user pastes image data, there are 2 items: the file name (at index 0) and the file (at index 1)
                        // but if the user pastes plain text or HTML, /index 0/ is the data with markup and /index 1/ is the plain, unadorned text.

                        if (items[0].kind === 'string' && items[1].kind === 'file' && items[1].type.match(/^image/)) {

                            // If the user copied a file from Finder (OS X) and pasted it in the window, this is the result. This is also the result if a user takes a screenshot and pastes it.
                            // Unfortunately, you can't copy & paste a file from the desktop. It just returns the file's icon image data & filename (on OS X).

                        } else if (items[0].kind === 'string' && items[1].kind === 'string') {

                            // Get the plain text
                            items[0].getAsString(trigger('pasteText'));

                        }

                    } else {

                        var item = items[0];

                        if (!item) return;

                        if (item.type.match(/^image\//)) {

                            trigger('pasteImage', item.getAsFile());

                        } else if (item.type === 'text/plain') {

                            item.getAsString(trigger('pasteText'));

                        }
                    }

                } else {

                    if (clipboardData.types.length) {
                        text = clipboardData.getData('Text');
                        trigger('pasteText', text);
                    } else {
                        readImagesFromEditable(pasteBoard, trigger('pasteImage'));
                    }
                }

            } else if ((clipboardData = window.clipboardData)) {

                text = clipboardData.getData('Text');
                if (text) {
                    trigger('pasteText', text);
                } else {
                    readImagesFromEditable(pasteBoard, trigger('pasteImage'));
                }
            }

            setTimeout(function() {
                pasteBoard.empty();
            }, 1);
        };

        return $('<div/>')
            .prop('contentEditable', true)
            .css({
                width: 1,
                height: 1,
                position: 'fixed',
                left: -10000,
                overflow: 'hidden'
            })
            .on('paste', handler);
    };

})(jQuery);

这并不难理解。