gpt4 book ai didi

javascript - 使用 XHR 和 Web Worker 上传分块文件

转载 作者:行者123 更新时间:2023-12-02 17:57:36 25 4
gpt4 key购买 nike

大家好,新年快乐:)

我想使用 XHR 和 Web Worker 上传文件,发送文件 block 并在最后合并。问题是最终文件是空的,我认为问题出在 XHR 请求的内容类型中,该请求应该发送正确的“multipart/form-data”(上传 block 时),因为 PHP print_r($_FILES ) 返回一个空的 Array() 但在 Web Worker 中不可能使用 FormData()。请帮我解决这个问题:'(

index.html

<form onsubmit="return false" enctype="multipart/form-data">
<input id="file" type="file">
<div id="filedrop">or drop files here</div>
</form>

<script>

window.addEventListener("load", function() {
var fileselect = document.getElementById("file");
fileselect.addEventListener("change", FileSelectHandler, false);

var filedrag = document.getElementById("filedrop");
filedrag.addEventListener("dragover", FileDragHover, false);
filedrag.addEventListener("dragleave", FileDragHover, false);
filedrag.addEventListener("drop", FileSelectHandler, false);
}, false);

function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
}

function FileSelectHandler(e) {
FileDragHover(e);

var blob = e.target.files[0] || e.dataTransfer.files[0];

worker = new Worker("upload.webworker.js");
worker.postMessage(blob);

worker.onmessage = function(e) {
console.log(e);
};
}
</script>

uploadFile.php

<? 

if ($_GET['a'] == "chunk") {
$target = "upload/" . $_GET['name'] . '-' . $_GET['index'];
move_uploaded_file($_FILES['file']['tmp_name'], $target);
sleep(1);
} else {
$target = "upload/" . $_GET['name'];
$dst = fopen($target, 'wb');
$slices = (int)$_GET['slices'];

for ($i = 0; $i < $slices; $i++) {
$slice = $target . '-' . $i;
$src = fopen($slice, 'rb');
stream_copy_to_stream($src, $dst);
fclose($src);
unlink($slice);
}

fclose($dst);
}

?>

upload.webworker.js

function uploadChunk(blob, index, start, end, slices, slices2) {
var xhr = new XMLHttpRequest();

xhr.onload = function() {
slices--;

if (slices == 0) {
var xhrMerge = new XMLHttpRequest();
xhrMerge.open("POST", "uploadFile.php?a=merge&name=" + blob.name + "&slices=" + slices2);

xhrMerge.onload = function() {
self.close();
};

xhrMerge.send();
}
};

xhr.upload.onprogress = function(e) {
if (e.lengthComputable) self.postMessage(Math.round(100 / e.total * e.loaded)); //this doesn't work o.O
};

var chunk = blob.slice(start, end);

xhr.open("POST", "uploadFile.php?a=chunk&name=" + blob.name + "&index=" + index);
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=--------------------");
xhr.send(chunk);
}

self.onmessage = function(e) {
const BYTES_PER_CHUNK = 1024 * 1024 * 32;

var blob = e.data,
start = 0,
index = 0,
slices = Math.ceil(blob.size / BYTES_PER_CHUNK),
slices2 = slices;

while (start < blob.size) {
end = start + BYTES_PER_CHUNK;

if (end > blob.size) end = blob.size;

uploadChunk(blob, index, start, end, slices, slices2);

start = end;
index++;
}
};

PS:如果您愿意,请告诉我如何优化上传 =)

PPS:我应该利用同步 ajax 请求(仅在 Web Worker 中)?

PPPS:如果我使用 php://input 来读取 block ,会更好吗?

最佳答案

我使用以下代码解决了从 php://input 读取文件的问题:

$putdata = fopen("php://input", "r");
$fp = fopen($target, "w");

while ($data = fread($putdata, 16384)) {
fwrite($fp, $data);
}

fclose($fp);
fclose($putdata);

这样我就不需要写multipart/form-data的HTTP header了

关于javascript - 使用 XHR 和 Web Worker 上传分块文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20873193/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com