Javascript分块文件上载到PHP服务器

Javascript分块文件上载到PHP服务器,javascript,php,ajax,file-upload,fileapi,Javascript,Php,Ajax,File Upload,Fileapi,因此,我在javascript中有一个函数,用于将部分文件发送到服务器: function ajaxPartUpload(url, packageNo, file, attachmentId) { var packageMaxSize = 10240; //1048576; //10485760; //reduced for tests var packageCount = Math.ceil(file.size / packag

因此,我在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);
    }
正如预期的那样,我在post中获得了我发送的文件的二进制数据。 在指定的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的长度:对于一个块,我得到了两个完全不同的结果,最大1 MB的文件有“28KB”(来自ls-lash):

javascript:25755

菲律宾比索:36495

发生了什么事?当我厌倦了文本文件时,一切都很好

@编辑: 解决方案 在JS更改中:

blob: reader.result,

在PHP中

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


这就解决了问题。

尝试使用PHP文档推荐的“b”标志打开文件:

发件人:

为了便于移植,强烈建议您在使用fopen()打开文件时始终使用“b”标志

就这样吧:

$filePointer = fopen($destination_path, 'ab');
如果问题仍然存在,那么可能是由于并发性问题,因此您应该使用一些锁来保护上述调用,以确保没有不同的php进程同时写入该文件


您可以使用它,看看如何在这里使用它。

我已经在javascript中添加了atob,用于读取reader的结果,然后在使用base64_decode读取之前对数据进行解码。它解决了这个问题


问题是PHP以其他方式解释这个二进制数据,可能是字符串,我真的不知道。无论如何,发送一个“稍微”大一点的编码数据可以省去很多神经。

我确信没有其他进程可以处理该文件。我已按建议添加了b,但没有任何帮助。您也可以尝试
$write=fwrite($filePointer,$\u POST['blob']),strlen($\u POST['blob'])我尝试了一些“strlen”魔术,我已经得出了结果。请将解决方案代码添加到您的答案中,然后您可以将您的答案标记为已接受的答案(绿色标记)。很高兴听到你解决了这个问题。
$written = fwrite($filePointer, base64_decode($_POST['blob']));
$filePointer = fopen($destination_path, 'ab');