所以我在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']));
解决了这个问题。
答案 0 :(得分:1)
我在javascript中添加了atob来读取我的结果,然后在使用base64_decode读取之前解码数据。它解决了这个问题。
问题是PHP以其他方式解释这个二进制数据,也许是字符串,我真的不知道。无论如何,发送“比特”更大的编码数据可以节省很多麻烦。
答案 1 :(得分:0)
尝试使用'b'标志打开文件,因为它是PHP文档推荐的:
来自http://php.net/manual/en/function.fopen.php:
为了便于携带,强烈建议您在使用fopen()打开文件时始终使用'b'标志。
就这样吧:
$filePointer = fopen($destination_path, 'ab');
如果问题仍然存在,那么可能是因为并发问题,所以你应该用一些锁来保护上面的调用,以确保没有不同的php进程同时写入该文件。
您可以使用flock(),查看如何在此flock tutorial中使用它。