【问题标题】:How to receive php image data over copy-n-paste javascript with XMLHttpRequest如何使用 XMLHttpRequest 通过复制粘贴 javascript 接收 php 图像数据
【发布时间】:2013-08-05 23:57:40
【问题描述】:

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

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

  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() 显示)比实际图像大小大得多。但也许这与编码无关或由编码引起。

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

{"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 bytes (8 KB on disk) 的大小。

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

【问题讨论】:

  • 开发者控制台的网络标签显示什么。是实际通过网络提交的文件还是正在发送一个空表单。
  • 你的 reader.onload = function(event) { console.log(event.target.result); // data url! submitFileForm(event.target.result, 'paste'); }; 函数没有触发。

标签: php javascript xmlhttprequest image-uploading onpaste


【解决方案1】:

图像文件大小是否可能大于您的“upload_max_filesize”设置?(通常默认为 2 兆)

【讨论】:

  • 我怀疑,磁盘上的图像大小是 5,320 字节(磁盘上 8 KB)
【解决方案2】:

我猜该文件在 $_FILE 数组中而不是在 $_POST 中,因为它是一个文件。 如果没有,您可以将图像转换为字符串,然后将图像字符串作为 GET 请求发送。

【讨论】:

    【解决方案3】:

    我已经发布了一个完整的工作示例。之前的问题是您需要正确构建 blob。通过在数组符号中注入文件数据

    document.onpaste = function(e){
        var items = e.clipboardData.items;
        console.log(JSON.stringify(items));
        if (e.clipboardData.items[0].kind === 'file') {
                // get the blob
            var imageFile = items[0].getAsFile();
            console.log(imageFile);
            var reader = new FileReader();
            reader.onload = function(event) {
                console.log(event.target.result); // data url!
                submitFileForm(event.target.result, 'paste');
            };
            reader.readAsBinaryString(imageFile);
        }
    };
    
    function submitFileForm(file, type) {
        var formData = new FormData();
        var myBlob = new Blob([file], { "type" : "image/png"} );
        formData.append('file', myBlob, 'file.jpg');
        formData.append('submission-type', type);
    
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/task/file');
        xhr.onload = function () {
            if (xhr.status == 200) {
                console.log('all done: ');
            } else {
                console.log('Nope');
            }
        };
    
        xhr.send(formData);
    }
    

    【讨论】:

    • 对,我现在正确发送数据。然而,每次都会创建一个零字节的文件。我也尝试过使用 $_FILES 但我不确定这是否真的正确。有什么想法吗?
    • 听起来不错,但对我不起作用。文件大小保持 0 字节。请注意,Blob 将数组作为其第一个参数。此外,这样我所有的 $_POST 变量(例如“提交类型”)都被清除了,这意味着它们没有在 php 脚本中定义。你自己试过吗?如果您能帮助我,我将非常感激!
    • DevZer0 赏金活动开始!
    • 你能发布php部分吗? :)
    【解决方案4】:

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

    不,那是impossible。你可以粘贴的是例如截图和图片来自网络,what gmail does

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

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

    <?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>
    

    【讨论】:

    • pathinfo($_FILES['file']['name'])['extension'] 是空的 :(。如果你能告诉我如何获得图像扩展名,它是你的。:)
    • 完美,我只是用ajax代码替换XMLRequest,没关系,只取决于你使用的是什么。
    猜你喜欢
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 2010-10-04
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多