2017-09-23 177 views
1

我试图上传“大”文件到我的应用程序。用户必须能够上传200MB以下的视频文件,但似乎服务器会在4MB或30秒后丢弃连接,并且上传失败。使用PHP上传Dropzone.js失败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

一切工作时我上传一个文件2MB @ 1Mbps的/秒(我不知道,如果是与文件大小或转让时间的问题)

直播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的较小文件将工作)。

你能帮忙找出问题吗?

编辑做一些测试,我发现,脚本在执行30秒正好落,我已经tryed在脚本的顶部添加set_time_limit(0);,但没有再次改变

+0

那么,你的一些情况下,他们缺少休息。这可能无法修复您的代码,但您需要添加这些代码。 –

+0

*“我不认为与PDOquery相关”* - 它可能是,您的'VALUES(NULL,'0','0','0',$ fileName)'该文件名最有可能是一个字符串,可以失败,但我可能是错的。 –

+0

你能编辑你的文章,以便它包含这个html吗?也许那里有一些东西含有限制。如果您在本地服务器上运行此操作,请确保在进行这些更改后重新启动了所有服务,如果您确实进行了任何更改。也将最大执行时间设置为0。 –

回答

9

问题是XHR超时简称ajax调用配置。

为了避免这种情况,必须在DropZone.js初始参数中放入timeout: 180000(或者你想要的ms)。

$("#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超时。

UPDATE

由于@Brendon缪尔报道,您还可以插入0作为timeout禁用超时。

DropZone.js文档报告默认超时为0,这是不正确的,默认超时是30秒。 值为0将禁用超时。

+0

Web服务器级别还有可能会影响超时行为的设置。这一个帮助我:https://stackoverflow.com/questions/24127601/uwsgi-request-timeout-in-python –

+0

你也可以设置超时为0来禁用超时。默认情况下,它在文档中错误地报告为0,但实际上默认设置为30秒。 –

+0

感谢您的建议@BrendonMuir,我已更新我的回复。 – andreaem