上传 30 秒后,使用 PHP 上传 Dropzone.js 失败
Posted
技术标签:
【中文标题】上传 30 秒后,使用 PHP 上传 Dropzone.js 失败【英文标题】:Dropzone.js upload with PHP failed after 30 seconds upload 【发布时间】:2018-03-04 22:19:45 【问题描述】:我正在尝试将“大”文件上传到我的应用程序。用户必须能够上传小于 200MB 的视频文件,但似乎服务器在 4MB 或 30 秒后断开连接并且上传失败。
我已经将php.ini
file 中的所有参数设置为:
max_input_time = 320
max_execution_time = 320
max_file_uploads = 20
memory_limit = 512M
post_max_size = 201M
upload_max_filesize = 200M
当我上传 2MB @ 1Mbps/s 的文件时一切正常(我不知道是文件大小还是传输时间的问题)
可以在 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
query 无关,因为较小的 2MB 文件可以工作)。
您能帮忙找出问题吗?
编辑做一些测试,我发现脚本正好在执行 30 秒时下降,我尝试在脚本顶部添加 set_time_limit(0);
,但没有任何改变
【问题讨论】:
好吧,您的一些案例缺少休息时间。这可能无法修复您的代码,但您需要添加它们。 “我认为与 PDOquery 无关” - 可能是,您的VALUES (NULL, '0', '0', '0', $fileName)
文件名很可能是一个字符串并且可能会失败,但我可以不过是错的。
您可以编辑您的帖子以使其包含相应的 html 吗?也许那里有一些包含限制的东西。如果您在本地服务器上运行此程序,请确保在进行这些更改后重新启动所有服务(如果您确实进行了任何更改)。将最大执行时间也设置为 0。
@Fred-ii- PDOquery 不影响上传原因将在此之后执行,我知道它失败了,但是可以上传较小的文件。我可以为此粘贴生成的 HTML,但它是 Dropzone.js 的默认 HTML
@ßiansorÅ.Ålmerol 正如我在答案中写过两次,错误是 PHP 在大约 4MB 上传或未定义时间后断开连接。无论如何,问题可能与拒绝文件的 Drozone.js 有关
【参考方案1】:
问题在于 XHR 超时涉及 ajax 调用配置。
为避免这种情况,必须将timeout: 180000
(或您想要的毫秒数)放入DropZone.js
init 参数中。
$("#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");
);
这不会在使用DropZone.js
上传文件时导致30 seconds
超时。
更新
正如@Brendon Muir 报告的那样,您还可以将0
插入为timeout
以禁用超时。
DropZone.js 文档报告默认超时为 0,这是不正确的,默认超时为 30 秒。 值为 0 将禁用超时。
【讨论】:
Web 服务器级别的设置也可能会影响超时行为。这个帮助了我:***.com/questions/24127601/… 您也可以将超时设置为 0 以禁用超时。它在文档中默认错误地报告为 0,但实际上默认设置为 30 秒。 感谢您的建议@BrendonMuir,我已经更新了我的回复。 谢谢伙计,这正在工作我必须使用 0 以防上传更大的文件。 遇到了同样的问题,你的回答想出了解决方案【参考方案2】:我意识到这个问题有点老了,但是我在捕捉超时行为方面遇到了问题,并发现了这个解决方案,而不是在发送函数上捕捉到超时,如下所示:
$("#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');
;
);
【讨论】:
非常正确!对我来说,超时永远不会被错误回调捕获!虽然看起来像一个错误 我添加了发送: - 没有变化 - 只是服务器响应 0 代码。以上是关于上传 30 秒后,使用 PHP 上传 Dropzone.js 失败的主要内容,如果未能解决你的问题,请参考以下文章