我正在我的应用程序中开发一个文件上传部分。客户端是Vue.js,后端是PHP。以Laravel作为我的框架。
我正在使用Blob.slice()在客户端分割所选的文件(我还尝试了FileReader Api,Resumablejs,现在正在进行自己的实现)。数据是使用xhr (尝试使用Axios,XMLHTTPRequest)发送的,每个“片”或“块”都有一个请求。我在后端获取数据并将传入的文件保存为"chunk1“、"chunk2”.诸若此类。在接收到最后一个块时,我使用PHP合并这些块。
我的问题是合并的文件以某种方式损坏了。mp4s -不可玩或不可寻觅,前任-腐败,一些前任做好事,但并非所有(它的不可预测),一些小的pdfs生存。
失败尝试
multipart/form-data
--用存储保存块::put()或Storage::putFileAs() --用fopen保存块(文件,'wb‘或'ab'),fwrite(),fclose() --用file_put_contents保存块
发送切片数据
--保存已接收的块(base64编码),->使用base64_decode()读取每个块,同时将数据保存在新文件中-将接收到的所有块(base64编码)追加到一个文件中,->稍后创建一个新文件,解码该附加文件。(这是迄今为止最成功的一次尝试,但仍有一些文件被破坏,特别是前任)。
客户端代码..。
upload(file, start = 0, request = 0) {
let chunkSize = 1024 * 1024 * 3;
let end = (start + chunkSize) > file.fileObject.size ? file.fileObject.size : (start + chunkSize);
let reader = new FileReader();
let slice = file.fileObject.slice(start, end);
reader.onload = (e) => {
let data = {
fileName: file.fileObject.name,
chunkNumber: request + 1,
totalChunks: Math.ceil(file.fileObject.size / chunkSize),
chunk: reader.result.split(',')[1]
}
axios({
url: '/api/admin/batch-sessions/'+ this.batchSessionId +'/files',
method: 'POST',
data: data,
headers: {'Content-Type': 'application/json'}
})
.then(res => {
start += chunkSize;
request++;
if (start <= file.fileObject.size) {
this.upload(file, start, request);
}
})
.catch(err => {
console.log(err.message);
});
}
reader.readAsDataURL(slice);
}服务器端代码..。
public function handle()
{
$chunks = Storage::disk('s3-upload-queue')
->files($this->directory);
$mergedFile = Storage::disk('s3-upload-queue')->path($this->directory.'/'.basename($this->directory));
$base64File = Storage::disk('s3-upload-queue')->path($this->directory.'/'.basename($this->directory).'.b64');
$mfs = fopen($mergedFile, 'wb');
$b64fs = fopen($base64File, 'r');
fwrite($mfs, base64_decode(fread($b64fs, filesize($base64File))));
fclose($mfs);
fclose($b64fs);
}实际上,我对不同的编码没有深入的了解,我在这里读到了关于base64在堆栈溢出上分块的内容,并试图创建大小的“片段”(1024 * 1024 * 3)。这是使用base64编码传输成功合并大多数文件的时候。但这也是不可预测的。有些文件仍然被损坏。我正试着正确地理解这一点。如果需要更多的信息,请告诉我。谢谢。
发布于 2022-10-28 12:04:35
chunk: reader.result.split(',')[1]那是什么?您要删除base64前缀吗?它不存在于块中,所以您的块始终是空的,因为索引"1“中没有任何内容,因为字符串没有被拆分。
我也会使用这样的代码来获取blob:
let blob = file.slice(offset, length + offset);
file.fileReader.readAsBinaryString(blob);
file.fileReader.onload = async function() {
let base64 = btoa(this.result)
// Do whatever you want
}关于腐败,你还想知道是否所有的块都发送成功了?您是否在服务器端,而不仅仅是在客户端保存块日志?
https://stackoverflow.com/questions/70642207
复制相似问题