Dropzone.js 上传 PHP 上传 30 秒后失败
Dropzone.js upload with PHP failed after 30 seconds upload
我正在尝试将 "large" 文件上传到我的应用程序。用户必须能够上传最小小于 200MB 的视频文件,但服务器似乎在 4MB 或 30 秒后断开连接并且上传失败。
我已经在 php.ini
文件中设置了所有参数,如下所示:
max_input_time = 320
max_execution_time = 320
max_file_uploads = 20
memory_limit = 512M
post_max_size = 201M
upload_max_filesize = 200M
当我以 1Mbps/s 的速度上传 2MB 的文件时一切正常(我不知道是否与文件大小或传输时间有关)
可在 php_info
访问实时 php_info() 文件
虽然这里是DropZone.js conf:
$("#dZUpload").dropzone({
url: "/ajax/admin/admin.acceptVideo.php",
maxFilesize: 209715200,
acceptedFiles: "video/*",
addRemoveLinks: true,
dataType: "HTML",
data: { id: '' },
success: function (file, response, data) {
var imgName = response;
file.previewElement.classList.add("dz-success");
$('#form_video').val(imgName);
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
}
});
Dropzone.autoDiscover = false;
Dropzone.prototype.defaultOptions.dictRemoveFile = "Rimuovi file";
Dropzone.prototype.defaultOptions.dictCancelUpload = "Annulla";
这是处理上传的 PHP 脚本:
<?php
require_once '../db.config.php';
header('Content-Type: text/plain; charset=utf-8');
ini_set('upload_max_filesize', '200M');
ini_set('post_max_size', '201M');
ini_set('max_input_time', 320);
ini_set('memory_limit', '256M');
try {
if (
!isset($_FILES['file']['error']) ||
is_array($_FILES['file']['error'])
) {
throw new RuntimeException('Invalid parameters.');
}
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
break;
case UPLOAD_ERR_INI_SIZE:
break;
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
break;
default:
throw new RuntimeException('Unknown errors.');
break;
}
// check filesize.
if ($_FILES['file']['size'] > 209715200) {
throw new RuntimeException('Exceeded filesize limit.');
}
// Check MIME Type.
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['file']['tmp_name']),
array(
'mp4' => 'video/mp4',
'mov' => 'video/mov',
'avi' => 'video/avi',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
// name uniquely.
$fileName = sha1_file($_FILES['file']['tmp_name']);
if (!move_uploaded_file($_FILES['file']['tmp_name'], sprintf('/var/www/html/beta.vedocompro.it/web/webtemp/%s.%s', $fileName, $ext ))) {
throw new RuntimeException('Failed to move uploaded file.');
}
try {
$PDO = new PDO('mysql:host=' . $DB_HOST . ';dbname=' . $DB_NAME,$DB_USER,$DB_PASS);
$insert = $PDO->prepare("INSERT INTO `videos` (`id`, `aid`, `accepted`, `uid`, `dir`) VALUES (NULL, '0', '0', '0', $fileName);");
$insert->execute();
echo $fileName;
} catch(PDOException $exception) {
echo $exception;
}
} catch (RuntimeException $e) {
echo $e->getMessage();
}
所以一切似乎都正常,但服务器在出现错误后断开连接(我不认为与 PDO
查询有关,因为 2MB 的较小文件可以工作)。
能否请您帮助确定问题所在?
EDIT 做一些测试我发现脚本恰好在执行 30 秒时下降,我尝试在脚本顶部添加 set_time_limit(0);
但什么也没有改变
问题出在参考 ajax 调用配置的 XHR 超时中。
为避免这种情况,必须在 DropZone.js
初始化参数中放入 timeout: 180000
(或您想要的毫秒数)。
$("#dZUpload").dropzone({
url: "/ajax/admin/admin.acceptVideo.php",
maxFilesize: 209715200,
acceptedFiles: "video/*",
addRemoveLinks: true,
dataType: "HTML",
timeout: 180000,
success: function (file, response, data) {
// Do things on Success
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
}
});
这不会导致 30 seconds
使用 DropZone.js
上传文件时超时。
更新
正如@Brendon Muir 报道的那样,您还可以将 0
作为 timeout
插入以禁用超时。
The DropZone.js Documentation reports that the default timeout is 0, that's incorrect, the default timeout is 30 seconds. A value of 0 will disable the timeout.
我意识到这个问题有点陈旧,但我在捕获超时行为时遇到了问题,并发现了这个解决方案,而不是在发送函数上捕获超时,如下所示:
$("#dZUpload").dropzone({
url: "/ajax/admin/admin.acceptVideo.php",
maxFilesize: 209715200,
acceptedFiles: "video/*",
addRemoveLinks: true,
dataType: "HTML",
data: { id: '' },
success: function (file, response, data) {
var imgName = response;
file.previewElement.classList.add("dz-success");
$('#form_video').val(imgName);
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
},
//Called just before each file is sent
sending: function(file, xhr, formData) {
//Execute on case of timeout only
xhr.ontimeout = function(e) {
//Output timeout error message here
console.log('Server Timeout');
};
}
});
我正在尝试将 "large" 文件上传到我的应用程序。用户必须能够上传最小小于 200MB 的视频文件,但服务器似乎在 4MB 或 30 秒后断开连接并且上传失败。
我已经在 php.ini
文件中设置了所有参数,如下所示:
max_input_time = 320
max_execution_time = 320
max_file_uploads = 20
memory_limit = 512M
post_max_size = 201M
upload_max_filesize = 200M
当我以 1Mbps/s 的速度上传 2MB 的文件时一切正常(我不知道是否与文件大小或传输时间有关)
可在 php_info
访问实时 php_info() 文件虽然这里是DropZone.js conf:
$("#dZUpload").dropzone({
url: "/ajax/admin/admin.acceptVideo.php",
maxFilesize: 209715200,
acceptedFiles: "video/*",
addRemoveLinks: true,
dataType: "HTML",
data: { id: '' },
success: function (file, response, data) {
var imgName = response;
file.previewElement.classList.add("dz-success");
$('#form_video').val(imgName);
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
}
});
Dropzone.autoDiscover = false;
Dropzone.prototype.defaultOptions.dictRemoveFile = "Rimuovi file";
Dropzone.prototype.defaultOptions.dictCancelUpload = "Annulla";
这是处理上传的 PHP 脚本:
<?php
require_once '../db.config.php';
header('Content-Type: text/plain; charset=utf-8');
ini_set('upload_max_filesize', '200M');
ini_set('post_max_size', '201M');
ini_set('max_input_time', 320);
ini_set('memory_limit', '256M');
try {
if (
!isset($_FILES['file']['error']) ||
is_array($_FILES['file']['error'])
) {
throw new RuntimeException('Invalid parameters.');
}
switch ($_FILES['file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
break;
case UPLOAD_ERR_INI_SIZE:
break;
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
break;
default:
throw new RuntimeException('Unknown errors.');
break;
}
// check filesize.
if ($_FILES['file']['size'] > 209715200) {
throw new RuntimeException('Exceeded filesize limit.');
}
// Check MIME Type.
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['file']['tmp_name']),
array(
'mp4' => 'video/mp4',
'mov' => 'video/mov',
'avi' => 'video/avi',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
// name uniquely.
$fileName = sha1_file($_FILES['file']['tmp_name']);
if (!move_uploaded_file($_FILES['file']['tmp_name'], sprintf('/var/www/html/beta.vedocompro.it/web/webtemp/%s.%s', $fileName, $ext ))) {
throw new RuntimeException('Failed to move uploaded file.');
}
try {
$PDO = new PDO('mysql:host=' . $DB_HOST . ';dbname=' . $DB_NAME,$DB_USER,$DB_PASS);
$insert = $PDO->prepare("INSERT INTO `videos` (`id`, `aid`, `accepted`, `uid`, `dir`) VALUES (NULL, '0', '0', '0', $fileName);");
$insert->execute();
echo $fileName;
} catch(PDOException $exception) {
echo $exception;
}
} catch (RuntimeException $e) {
echo $e->getMessage();
}
所以一切似乎都正常,但服务器在出现错误后断开连接(我不认为与 PDO
查询有关,因为 2MB 的较小文件可以工作)。
能否请您帮助确定问题所在?
EDIT 做一些测试我发现脚本恰好在执行 30 秒时下降,我尝试在脚本顶部添加 set_time_limit(0);
但什么也没有改变
问题出在参考 ajax 调用配置的 XHR 超时中。
为避免这种情况,必须在 DropZone.js
初始化参数中放入 timeout: 180000
(或您想要的毫秒数)。
$("#dZUpload").dropzone({
url: "/ajax/admin/admin.acceptVideo.php",
maxFilesize: 209715200,
acceptedFiles: "video/*",
addRemoveLinks: true,
dataType: "HTML",
timeout: 180000,
success: function (file, response, data) {
// Do things on Success
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
}
});
这不会导致 30 seconds
使用 DropZone.js
上传文件时超时。
更新
正如@Brendon Muir 报道的那样,您还可以将 0
作为 timeout
插入以禁用超时。
The DropZone.js Documentation reports that the default timeout is 0, that's incorrect, the default timeout is 30 seconds. A value of 0 will disable the timeout.
我意识到这个问题有点陈旧,但我在捕获超时行为时遇到了问题,并发现了这个解决方案,而不是在发送函数上捕获超时,如下所示:
$("#dZUpload").dropzone({
url: "/ajax/admin/admin.acceptVideo.php",
maxFilesize: 209715200,
acceptedFiles: "video/*",
addRemoveLinks: true,
dataType: "HTML",
data: { id: '' },
success: function (file, response, data) {
var imgName = response;
file.previewElement.classList.add("dz-success");
$('#form_video').val(imgName);
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
},
//Called just before each file is sent
sending: function(file, xhr, formData) {
//Execute on case of timeout only
xhr.ontimeout = function(e) {
//Output timeout error message here
console.log('Server Timeout');
};
}
});