问题描述
我正在尝试与朋友为另一个项目制作一个在线文件管理器,当上传大于 1GB 的文件时,该进程要么崩溃(firefox),要么成功但接收到的文件重量为 0 字节(铬)。>
JS:
function uploadFile(fileInputId,fileIndex) {
//send file name
try {
var fileName = document.getElementById('fileUploader').files[0].name;
}
catch {
document.getElementById('uploadStatus').innerHTML = `<font color="red">Mettre un fichier serait une bonne idée.</font>`;
return false;
}
document.cookie = 'fname=' + fileName;
//take file from input
const file = document.getElementById(fileInputId).files[fileIndex];
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onloadend = function(event) {
ajax = new XMLHttpRequest();
//send data
ajax.open("POST",'uploader.PHP',true);
//all browser supported sendAsBinary
XMLHttpRequest.prototype.mySendAsBinary = function(text) {
var data = new ArrayBuffer(text.length);
var ui8a = new Uint8Array(data,0)
for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
if (typeof window.Blob == "function") {
var blob = new Blob([data]);
}else {
var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
bb.append(data);
var blob = bb.getBlob();
}
this.send(blob);
}
//track progress
var eventSource = ajax.upload || ajax;
eventSource.addEventListener('progress',function(e) {
//percentage
var position = e.position || e.loaded;
var total = e.totalSize || e.total;
var percentage = Math.round((position/total)*100);
document.getElementById('uploadStatus').innerHTML = `${percentage}%`;
});
ajax.onreadystatechange = function() {
if(ajax.readyState == 4 && ajax.status == 200) {
document.getElementById('uploadStatus').innerHTML = this.responseText;
}
}
ajax.mySendAsBinary(event.target.result);
}
}
PHP:
//MysqL login
$conn = new PDO([Redacted]);
//file info
$fileName = $_COOKIE['fname'];
$targetDir = "uploads/";
$targetFile = $targetDir.$fileName;
$fileNameRaw = explode('.',$fileName)[0]; //file name with no extension
$tempFilePath = $targetDir.$fileNameRaw.'.tmp';
if (file_exists($targetFile)) {
echo '<font color="red">Un fichier du même nom existe déjà.</font>';
exit();
}
//read from stream
$inputHandler = fopen('PHP://input','r');
//create temp file to store data from stream
$fileHandler = fopen($tempFilePath,'w+');
//store data from stream
while (true) {
$buffer = fgets($inputHandler,4096);
if (strlen($buffer) == 0) {
fclose($inputHandler);
fclose($fileHandler);
break;
}
fwrite($fileHandler,$buffer);
}
//when finished
rename($tempFilePath,$targetFile);
chmod($targetFile,0777);
echo 'Fichier envoyé avec succès !';
$bddInsert = $conn->prepare('INSERT INTO files(nom,chemin) VALUES(?,?)');
$bddInsert->execute(array($fileName,$targetFile));
在我的 PHP.ini 中,
max_execution_time 设置为 0
max_input_time 到 -1
我的帖子最大和上传最大大小为 4G
我正在使用 apache2
解决方法
如果您不需要文件,则不应使用 fileReader 读取文件。
只需将文件 (blob) 直接发送到您的 ajax 请求并避免 FileReader
function uploadFile (fileInputId,fileIndex) {
// Send file name
try {
var fileName = document.getElementById('fileUploader').files[0].name;
}
catch {
document.getElementById('uploadStatus').innerHTML = `<font color="red">Mettre un fichier serait une bonne idée.</font>`;
return false;
}
document.cookie = 'fname=' + fileName;
// Take file from input
const file = document.getElementById(fileInputId).files[fileIndex];
const ajax = new XMLHttpRequest();
// send data
ajax.open("POST",'uploader.php',true);
// track progress
ajax.upload.addEventListener('progress',function(e) {
// percentage
var position = e.position || e.loaded;
var total = e.totalSize || e.total;
var percentage = Math.round((position/total)*100);
document.getElementById('uploadStatus').innerHTML = `${percentage}%`;
});
ajax.onreadystatechange = function() {
if (ajax.readyState == 4 && ajax.status == 200) {
document.getElementById('uploadStatus').innerHTML = this.responseText;
}
}
ajax.send(file)
}