Javascript chunked文件上传到PHP Server(Javascript chunked file upload to PHP Server)

所以我在javascript中有这个函数将文件的一部分发送到服务器:

function ajaxPartUpload(url, packageNo, file, attachmentId) { var packageMaxSize = 10240; //1048576; //10485760; //reduced for tests var packageCount = Math.ceil(file.size / packageMaxSize); var start = packageNo * packageMaxSize; var stop = (packageNo+1) * packageMaxSize - 1; if ((packageNo+1) === packageCount || packageCount === 0) { stop = file.size - 1; } var blob = file.slice(start, stop); var reader = new FileReader(); reader.onloadend = function (evt) { if (evt.target.readyState === FileReader.DONE) { var data = { blob: reader.result, partNo: packageNo, lastPartNo: packageCount, fileName: file.name, fileType: file.type, fileSize: file.size, attachmentId: attachmentId, multipart: true }; $.ajax({ url: url, type: 'post', dataType: 'json', data: data, success: function(response) { if (response.continue === false) { return true; } else { ajaxPartUpload(url, packageNo+1, file, response.attachmentId); } } }); } }; reader.readAsBinaryString(blob); }

并且它按预期工作,我发布了我正在发送的文件的二进制数据。 在指定的URL下我有脚本基本上这样做:

$attachment = V()->Attachment->find($_POST['attachmentId']); $destination_path = $attachment->getPath(); $filePointer = fopen($destination_path, 'a'); $written = fwrite($filePointer, $_POST['blob']); if ($written == false ) { throw new Exception('File data not written'); } fclose($filePointer);

只要我有文本文件就可以,但是当我尝试发送二进制文件时,我正在恢复的文件大小大约50%,并且已损坏,如果我将块大小设置得足够大并不重要将所有文件保存在一个http请求中。 我做错了什么?

在发送之前我已经在javascript中丢弃了'blob'的长度,并且在php中收集了blob的长度:我有2个完全不同的结果,一个块最大1 MB文件有'28KB'(来自ls -lash):

javascript:25755

php:36495

发生了什么事? 当我累了文本文件时一切都还可以。

@EDIT:JS改变的解决方案:

blob: reader.result,

blob: window.btoa(reader.result),

在PHP中

$written = fwrite($filePointer, $_POST['blob']);

$written = fwrite($filePointer, base64_decode($_POST['blob']));

解决了这个问题。

So I have this function in javascript to send parts of file to server:

function ajaxPartUpload(url, packageNo, file, attachmentId) { var packageMaxSize = 10240; //1048576; //10485760; //reduced for tests var packageCount = Math.ceil(file.size / packageMaxSize); var start = packageNo * packageMaxSize; var stop = (packageNo+1) * packageMaxSize - 1; if ((packageNo+1) === packageCount || packageCount === 0) { stop = file.size - 1; } var blob = file.slice(start, stop); var reader = new FileReader(); reader.onloadend = function (evt) { if (evt.target.readyState === FileReader.DONE) { var data = { blob: reader.result, partNo: packageNo, lastPartNo: packageCount, fileName: file.name, fileType: file.type, fileSize: file.size, attachmentId: attachmentId, multipart: true }; $.ajax({ url: url, type: 'post', dataType: 'json', data: data, success: function(response) { if (response.continue === false) { return true; } else { ajaxPartUpload(url, packageNo+1, file, response.attachmentId); } } }); } }; reader.readAsBinaryString(blob); }

And It's working as expected, I get in post the binary data of files I'm sending. Under specified url I have script that basicly do this:

$attachment = V()->Attachment->find($_POST['attachmentId']); $destination_path = $attachment->getPath(); $filePointer = fopen($destination_path, 'a'); $written = fwrite($filePointer, $_POST['blob']); if ($written == false ) { throw new Exception('File data not written'); } fclose($filePointer);

And as long as I have text files it's ok, but when I try to send binary file, the files I'm reciving are about 50% bigger in size, and corrupted, it doesn't matter if I make chunk size big enough to hold all file in one http request or not. What I'm doing wrong?

I have dumped length of 'blob' in javascript right before send and length of recived blob in php: I've got 2 compleatly diffrent results for one chunk max 1 MB file has '28KB' (got from ls -lash):

javascript: 25755

php: 36495

What happend? When I've tired text file all was ok.

@EDIT: Solution in JS change:

blob: reader.result,

to

blob: window.btoa(reader.result),

AND in PHP

$written = fwrite($filePointer, $_POST['blob']);

to

$written = fwrite($filePointer, base64_decode($_POST['blob']));

that solves the problem.

最满意答案

我在浏览器的结果中添加了javascript中的atob,然后在使用base64_decode读取之前解码数据。 它解决了这个问题。

问题是PHP以其他方式解释这个二进制数据,也许是字符串,我真的不知道。 无论如何,发送“比特”更大的编码数据可以节省很多麻烦。

I've added atob in javascript on my result from reader, and then decoded data before reading with base64_decode. It solves the problem.

The problem is that PHP interprets this binary data in some other way, as string perhaps, I don't really know. Anyway sending a 'bit' bigger encoded data saves a lot of nerves.

更多推荐