web-dev-qa-db-ja.com

PHPを使用したDropzone.jsのアップロードは、30秒のアップロード後に失敗しました

「大きな」ファイルをアプリケーションにアップロードしようとしています。ユーザーは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();

}
_

だからすべては問題ないようですが、サーバーは何かが間違った後に接続をドロップします(私はPDOqueryに関連しているとは思わないので、2MBの小さなファイルが機能します)。

問題の特定を手伝っていただけませんか?

[〜#〜] edit [〜#〜]いくつかのテストを実行すると、スクリプトが実行の30秒で正確にドロップすることがわかり、set_time_limit(0);を追加しようとしましたスクリプトの先頭ですが、何も変更されていません

10
andreaem

問題は、jax呼び出し構成を参照するXHRタイムアウトにありました。

これを回避するには、timeout: 180000 initパラメータにDropZone.js(またはミリ秒単位で必要なもの)を挿入する必要があります。

$("#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が報告したように、0timeoutとして挿入してタイムアウトを無効にすることもできます。

DropZone.jsドキュメントは、デフォルトのタイムアウトが0であると報告していますが、これは誤りです。デフォルトのタイムアウトは30秒です。 値0はタイムアウトを無効にします。

50
andreaem

私はこの質問が少し古いことに気づきましたが、タイムアウト動作のキャッチに問題があり、以下に示すようにタイムアウトが送信機能でキャッチされる代わりにこの解決策を発見しました:

$("#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');

         };
     }
});
1
karen