如何使用 XMLHttpRequest 通过复制粘贴 javascript 接收 php 图像数据

我尝试制作一种类似于 GMail 使用的图像上传功能.您从桌面复制 (CTRL-C) 图像并将其粘贴 (CTRL-V) 到网站上.然后通过 XMLHttpRequest 将图像上传到处理传入文件的 php 脚本,其中处理"意味着重命名并存储在服务器上.

I try to make an image-upload functionality similar to the one GMail uses. You copy (CTRL-C) an image from your desktop and paste (CTRL-V) it onto the website. The image is then uploaded via a XMLHttpRequest to a php-script that handles the incoming file, whereby "handling" means renaming and storing on the server.

我已经可以获取图像(和数据),但是我无法成功提交和接收 XMLHttpRequest.我的 Javascript 代码如下所示:

I can already fetch the image (and -data), but I am unable to successfully submit and receive the XMLHttpRequest. My Javascript code looks like that:

  document.onpaste = function(e){
        var items = e.clipboardData.items;
        console.log(JSON.stringify(items));
        if (e.clipboardData.items[1].kind === 'file') {
            // get the blob
            var imageFile = items[1].getAsFile();
            console.log(imageFile);
            var reader = new FileReader();
            reader.onload = function(event) {
                console.log(event.target.result); // data url!
                submitFileForm(event.target.result, 'paste');
            };
        }
    };

 function submitFileForm(file, type) {
        var formData = new FormData();
        formData.append('file', file);
        formData.append('submission-type', type);

        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'php/image-upload.php');
        xhr.onload = function () {
            if (xhr.status == 200) {
                console.log('all done: ');
            } else {
                console.log('Nope');
            }
        };

        xhr.send(formData);
    }

处理php(php/image-upload.php)如下:

$base64string = $_POST['file'];
file_put_contents('img.png', base64_decode($base64string));

我认为 $_POST['file'] 保持为空,但我不确定.更重要的是,我还遇到blob 大小"(使用 console.log() 显示)比实际图像大小大得多.但也许这与编码无关或由编码引起.

I think the $_POST['file'] stays empty, but I am not sure. What's more, I also encounter the "blob size" (displayed with console.log()) is way larger than the actual image size. But maybe that's no matter or caused by encodings.

开发者控制台会显示这个.

The developer console displays this.

{"0":{"type":"text/plain","kind":"string"},"1":{"type":"image/png","kind":"file"},"length":2} image-upload.js:8
Blob {type: "image/png", size: 135619, slice: function}

如果我通过右键单击实际图像文件来查看文件信息,它会显示 5,320 字节(磁盘上 8 KB) 大小.

If I view the file-info by right-clicking the actual image file, it shows 5,320 bytes (8 KB on disk) in size.

我不一定需要使用 XMLHttpRequest,这正是我首先想到的.如果有更好的方法可以使用 javascript 实现将图像实时上传到服务器,请告诉我们.

I do not necessarily need to use a XMLHttpRequest, it was just what came to my mind first. If there's a better way of achieving realtime image-uploading to a server with javascript, please let us know.

推荐答案

您从桌面复制 (CTRL-C) 图像并将其粘贴 (CTRL-V) 到网站上.

you copy (CTRL-C) an image from your desktop and paste (CTRL-V) it onto the website.

不,那是不可能.你可以粘贴的是例如来自网络的屏幕截图和图片,这就是 gmail 的作用.

No, that is impossible. What you can paste is e.g. screenshots and images from the web, that's what gmail does.

你最大的错误是当你已经有一个文件时使用 FileReader,当有一个适当的 HTTP 上传而不是临时 base64 POST 参数时,$_FILES 数组被填充.要进行正确的 HTTP 上传,您只需 .append() 一个文件或 blob 对象(Files 是 Blobs).

Your biggest mistake is using FileReader when you already have a file, the $_FILES array is filled when there is a proper HTTP upload not for ad hoc base64 POST param. To do a proper HTTP upload, you just .append() a file or blob object (Files are Blobs).

这是一个独立的 PHP 文件,应该可以正常工作,托管文件,打开它是一个页面,截取屏幕截图,然后将其粘贴到页面上,几秒钟后图像应该出现在页面上.

This is a stand-alone PHP file that should just work, host the file, open it is a page, take a screenshot, then paste it while on the page and after a few seconds the image should appear on the page.

<?php
if( isset( $_FILES['file'] ) ) {
    $file_contents = file_get_contents( $_FILES['file']['tmp_name'] );
    header("Content-Type: " . $_FILES['file']['type'] );
    die($file_contents);
}
else {
    header("HTTP/1.1 400 Bad Request");
}
print_r($_FILES);
?>

<script>
document.onpaste = function (e) {
    var items = e.clipboardData.items;
    var files = [];
    for( var i = 0, len = items.length; i < len; ++i ) {
        var item = items[i];
        if( item.kind === "file" ) {
            submitFileForm(item.getAsFile(), "paste");
        }
    }

};

function submitFileForm(file, type) {
    var extension = file.type.match(//([a-z0-9]+)/i)[1].toLowerCase();
    var formData = new FormData();
    formData.append('file', file, "image_file");
    formData.append('extension', extension );
    formData.append("mimetype", file.type );
    formData.append('submission-type', type);

    var xhr = new XMLHttpRequest();
    xhr.responseType = "blob";
    xhr.open('POST', '<?php echo basename(__FILE__); ?>');
    xhr.onload = function () {
        if (xhr.status == 200) {
            var img = new Image();
            img.src = (window.URL || window.webkitURL)
                .createObjectURL( xhr.response );
            document.body.appendChild(img);
        }
    };

    xhr.send(formData);
}
</script>

相关文章