使用 HTML5 分 block ,我可以用较小的部分上传文件。但是当它开始使用多个 http POST 请求时问题就开始了,这将导致计算机速度变慢,或者可能崩溃。无论如何在一个 http 请求下有拆分文件..所以如果我有 5 个文件,即使我使用 html5 split chunk,它也只有 5 个 http 请求
例如:如果我上传 5 个文件,每个文件将被拆分为 1mb 的 block ,因此如果第一个文件是 10mb,那么它将变成 10 个 1mb 的 block 。问题是,每个 block 都将受到 1 个 http 请求,因此只有第一个文件将是 10 个 HTTP 请求。 想象一下,如果我有 1gb 的文件,它将变成 1000 个 HTTP 请求并减慢计算机的速度。
这是示例代码:
//Prepare element progress after the page load completely
var uploaders = [];
var totalChunks = 0;
var progress;
var bars;
$(document).ready(function() {
//progress = document.querySelector('progress');
//bars = document.querySelector('#bars');
});
//function for after the button is clicked, slice the file
//and call upload function
function sendRequest() {
//clean the screen
//bars.innerHTML = '';
var file = document.getElementById('fileToUpload');
for(var i = 0; i < file.files.length; i++) {
var blob = file.files[i];
var originalFileName = blob.name;
var filePart = 0
const BYTES_PER_CHUNK = 10 * 1024 * 1024; // 10MB chunk sizes.
const SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
totalChunks = Math.ceil(SIZE / BYTES_PER_CHUNK);
while( start < SIZE ) {
if (blob.webkitSlice) {
//for Google Chrome
var chunk = blob.webkitSlice(start, end);
} else if (blob.mozSlice) {
//for Mozilla Firefox
var chunk = blob.mozSlice(start, end);
}
uploadFile(chunk, originalFileName, filePart, totalChunks, i);
filePart++;
start = end;
end = start + BYTES_PER_CHUNK;
}
}
}
function uploadFile(blobFile, fileName) {
var fd = new FormData();
fd.append("fileToUpload", blobFile);
var xm = $.ajax({
url: "upload.php"+"?"+"file1="+fileName,
type: "POST",
data: fd,
processData: false,
contentType: false,
});
}
function uploadFile(blobFile, fileName, filePart, totalChunks, divBarsSelector) {
if(filePart == 0) {
bars = document.querySelector('#bars' + divBarsSelector);
}
var progress = document.createElement('progress');
progress.min = 0;
progress.max = 100;
progress.value = 0;
bars.appendChild(progress);
var fd = new FormData();
fd.append("fileToUpload", blobFile);
var xhr = new XMLHttpRequest();
xhr.open("POST", "upload.php"+"?"+"file="+fileName + filePart, true);
xhr.onload = function(e) {
//make sure if finish progress bar at 100%
progress.value = 100;
//counter if everything is done using stack
uploaders.pop();
if (!uploaders.length) {
bars.appendChild(document.createElement('br'));
bars.appendChild(document.createTextNode('DONE :)'));
//mergeFile(fileName, totalChunks);
}
};
// Listen to the upload progress for each upload.
xhr.upload.onprogress = function(e) {;
if (e.lengthComputable) {
progress.value = (e.loaded / e.total) * 100;
}
};
uploaders.push(xhr);
xhr.send(fd);
}
用于接收的服务器部分将是 upload.php
$target_path = "uploads/";
$tmp_name = $_FILES['fileToUpload']['tmp_name'];
$size = $_FILES['fileToUpload']['size'];
$name = $_FILES['fileToUpload']['name'];
$originalName = $_GET['file'];
print_r("*******************************************\n");
print_r($originalName);
print_r("\n");
print_r($_FILES);
print_r("\n");
print_r("*******************************************\n");
$target_file = $target_path . basename($name);
//Result File
$complete = $originalName;
$com = fopen("uploads/".$complete, "ab");
error_log($target_path);
if ( $com ) {
// Read binary input stream and append it to temp file
$in = fopen($tmp_name, "rb");
if ( $in ) {
while ( $buff = fread( $in, 1048576 ) ) {
fwrite($com, $buff);
}
}
fclose($in);
fclose($com);
}
最佳答案
在阅读了您评论中的动机后,我想指出一些“误解”。首先,不建议将文件拆分然后一次上传所有拆分的部分。拆分文件的全部目的是不绕过 PHP 上传限制(如果适用,应该更改并且可能一个真正的解决方案*),而是通过按顺序执行不同的部分,这可以使客户端计算机上的负载最小,尤其是当您考虑上传 1GB 的内容时。无论哪种方式,都没有理由将文件拆分然后将其合并到一个请求中(尽管这在理论上可以使用 XMLHttpRequest2,但是如果您可以使用 XMLHttpRequest2 那么您就不必担心以任何一种方式拆分文件,因为它提供了必要的控件来干净地上传多个文件)。
*请注意,如果您这样做,您必须确保正确设置了 php 内存设置(以防止 php 在将其写入临时文件之前尝试将其完全加载到内存中,但这不应该我相信使用默认设置的最新版本的 PHP 会发生这种情况)。 (我觉得有必要补充一点,我已经有几年没有使用 PHP 和 PHP 上传了,所以我可能对最后一条评论有很大的误解)
无论哪种方式,将文件分 block 到大约 5-25MB(取决于您期望连接的好坏 :P )+ 顺序上传(如果 XMLHttpRequest2 可用,加上一个漂亮的进度条,否则每个 block 一个进度条)似乎是明智的在防止浏览器重载的同时要走的路。 (哦,如果你需要支持旧版浏览器,我真的建议你研究一下 flash uploader ,因为尽管 Apple 鼓吹 flash 是邪恶的,但在大多数(过时的)计算机上,它会给迄今为止最好的体验)
关于php - 如何在 1 个 http 请求下上传多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10743746/