简体   繁体   English

通过XMLHttpRequest从HTML5文件系统上传文件

[英]Upload file from HTML5 Filesystem by XMLHttpRequest

Trying to Upload some Images stored in Filesystem of Google Chrome. 尝试上传一些存储在Google Chrome文件系统中的图片。 But Im not able to upload the Image. 但是我无法上传图片。 Any Idea how to do it? 任何想法怎么做?

The Server receives an empty array. 服务器收到一个空数组。 The Code of posttest.php is just print_r($_POST) posttest.php的代码只是print_r($ _ POST)

 var xhr = new XMLHttpRequest();
    xhr.open('POST', '/posttest.php', true);
    xhr.onload = function(e) {
        if (this.status == 200) {
            console.log(this.responseText);
        }
    };
    window.resolveLocalFileSystemURL(image, function(fileEntry) {
        fileEntry.file(function(file) {
            var reader = new FileReader();
            reader.onloadend = function(e) {
                var formData = new FormData();
                formData.append('image', this.result);
                xhr.send(formData);
            };
            reader.readAsText(file);
        });
    });

this is the Javascript function that worked for me in chrome 这是在chrome中为我工作的Javascript函数

 function upload(filename) { var xhr = new XMLHttpRequest(); xhr.open("post", "upload.php", true); window.resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL; filename = 'filesystem:http://localhost/temporary/' + filename; window.resolveLocalFileSystemURL(filename, function(fileEntry) { fileEntry.file(function(file) { xhr.setRequestHeader("Content-Type", "multipart/form-data"); xhr.setRequestHeader("X-File-Name", file.name); xhr.setRequestHeader("X-File-Size", file.size); xhr.setRequestHeader("X-File-Type", file.type); xhr.send(file); }); }); } 

Now most people on the skip the upload.php taking it for granted. 现在,大多数人都跳过了upload.php,这是理所当然的。 But it is very important and so I paste it here: 但这非常重要,因此我将其粘贴在此处:

 <?php // I had to figure out what is getting passed using var_dump($_SERVER) $fn = (isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : false); if ($fn) { // AJAX call file_put_contents( 'uploads/' . $fn, file_get_contents('php://input') ); echo "$fn uploaded"; exit(); } ?> 

Hope this helps someone, I wasted an entire day to figure this out ! 希望这对某人有帮助,我浪费了一整天来解决这个问题!

First of all, your comment isn't exactly correct, the PHP code shouldn't even be receiving a blob. 首先,您的评论并不完全正确,PHP代码甚至不应该包含斑点。 It's just receiving text, because you read the file as text, while png images (and almost all image types) aren't supposed to be text, they're supposed to be binary. 它只是在接收文本,因为您以文本形式读取文件,而png图像(以及几乎所有图像类型)都不应该是文本,而应该是二进制。 And Blobs themselves are perfect for storing binary data, so you don't even need to use a FileReader , you can just send the Blob itself through XMLHttpRequest ! 而且Blob本身非常适合存储二进制数据,因此您甚至不需要使用FileReader ,您只需通过XMLHttpRequest发送Blob本身即可!

Here is how the revised fileEntry.file callback function should look: 这是修改后的fileEntry.file回调函数的外观:

fileEntry.file(function(file) {
    xhr.send(file);
});

It's that simple! 就这么简单! No need to read the Blob. 无需阅读Blob。 However, you need to do some more stuff on the PHP side now. 但是,您现在需要在PHP方面做更多的事情。 This code will write the contents of the uploaded image to disk, then create an <img> element that allows you to view it. 此代码会将上传的图像的内容写入磁盘,然后创建一个<img>元素,使您可以查看它。 Here's how the PHP /posttest.php should look for that: 这是PHP /posttest.php查找方式:

<?php
$rhand=fopen('php://input','r');
$cont=fread($rhand,filesize('php://input'));
fclose($rhand);
$whand=fopen('./uploaded.png','w');
fwrite($whand,$cont);
fclose($whand);
?>
<img src="uploaded.png">

It should be pretty clear what that does if you know that php://input is where php will get input from a post request if it doesn't have a MIME type that allows it to easily put it into $_POST (For example, when you have have a request with MIME type application/x-www-form-urlencoded , PHP recognizes it and is able to parse the POST contents into $_POST , but with a Blob, it doesn't, so it just outputs it out of php://input ) 如果您知道php://input是php将从POST请求中获取输入的地方(如果它没有允许将其轻松放入$_POST的MIME类型),那么应该很清楚该怎么做(例如,当您$_POST MIME类型为application/x-www-form-urlencoded的请求时,PHP会识别该请求,并能够将POST内容解析为$_POST ,但是对于Blob,它不会,因此只会将其输出的php://input

Please note that none of this is tested, please put a comment if it doesn't work and I'll try to fix it! 请注意,这些内容均未经过测试,如果无法使用,请发表评论,我会尝试修复它!

Having encountered the same challenge myself, I was able to come up with a very sleek solution. 我自己也遇到了同样的挑战,所以我提出了一个非常时尚的解决方案。 The key is to create a new Blob, from the file object returned by the fileEntry. 关键是从fileEntry返回的文件对象创建一个新的Blob。

window.resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;

    window.resolveLocalFileSystemURL(image, function (fileEntry) {
        fileEntry.file(function (file) {
            var formData = new FormData();
            var tempBlob=new Blob([this.result], {type:this.result.type});
            formData.append('image', tempBlob);

        });
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM