サポート » プラグイン » contactform7 添付ファイルサイズ

  • 解決済 sugiura

    (@sugiura)


    お世話になります。

    contactform7を使用させていただいており、必要なことは出来ているのですが、先日ひとつ問題が発生したためご存知の方がいらっしゃればご教授いただきたく書き込ませて頂きます。
    ファイル添付をさせているのですが、サイズが大きすぎた場合の問題が発生しています。

    フォームタグでlimitを設定した場合。例えば[file your-file limit:8mb]として、上限を超えたファイルを添付するとファイルサイズが大きい旨のエラーメッセージが出ます。
    それはいいのですが、フォームは同じとしてphp.iniの upload_max_filesize が10MBだとします。この時に9MBのファイルをアップすると先のエラーが出るのですが、10MBを超えるファイルをアップした場合にスピナーが周り続けていてずっと処理が終わらないようになります。
    flamingoも入れていますがこの場合は処理が終わっていないので送信記録が残りません。

    ひとまずバージョンを先ほど4.9にアップデートしたのですが、若干状況が変わり、10MBを超えるファイルを添付しようとすると[text* your-name]などの必須項目すべて(入力済)に「必須項目に入力してください。」のバリデーションエラーがつきます。なのでエラーなのはわかるのですが変な風になってしまいます。

    module/file.php
    では UPLOAD_ERR_INI_SIZEのようなエラーがあればアップロードに失敗している旨のメッセージが出そうなのですが、出てこないです。

    問題としては処理が終わってないように見えるのがよくなかったので、include/scripts.jsのajaxにタイムアウト処理を追加しようと思ったのですが、タイムアウトを指定するのであればここに入れたほうがいいという箇所があれば教えていただけると非常に助かります。

    何卒、宜しくお願いいたします。

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • サーバー側の容量について制限を超えた場合、マルチパートで転送をうけると、ファイルフォームからの受信を待ちますが、プログラムには到達していないということで終わらないなどないでしょうか。
    ファイルが取得できなければ即時エラーとして再度試みる旨を表示やいったん完了するなど、ボタンを押した後の動作が設定できるとよいのですがプラグインの仕様ままでしょうか。
    サーバー側の処理とのずれを埋めるためには別途サイズを取得確認する試みかプログラム自体に取得できなかった際エラーを返すよう動作を切り替える必要があるかなと思います。

    トピック投稿者 sugiura

    (@sugiura)

    ありがとうございます。
    終わらないというよりは失敗した際にスピナーgifからis-activeクラスを取る処理が入っていないような気がしています。

    今気になるのは、こちらのトピックでのエラーにならない点です。
    https://ja.wordpress.org/support/topic/contact-form-7-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB/

    もう少しエラーログも確認してみます。

    is-activeへのトリガについては、結局はサーバーからの返答が反映されるのを皆まっているのではないか、と思いました。
    リンクを拝見いたしますと「UPLOAD_ERR_NO_FILE」以外の動作をされている場合返事があるとの事ですので、ファイルのサイズがサーバー規制の上をいくと、プログラムのもとにはファイルが届かないのではないかと思います。
    $_FILES["uploadfile"]["size"]で容量を確認しようにも["uploadfile"]がサーバーの容量規制によって取り除かれ「UPLOAD_ERR_NO_FILE」となり、入っていないので["size"]が取得できないのではないでしょうか。
    まず$_FILES["uploadfile"]["error"]が否定形でないか着荷がエラーではないか、エラーであればそこでその旨提示し終了する、ファイルがありませんでしたといった結果にスイッチするなどの手段が必要かと思いました。
    これらはプラグインの中で処理されているべきことだと思いますので、斯様な動作であれば変更がむつかしいと思いますがUI上での対策としてはJavascriptでファイルの容量を確認して設定値以上であればファイルをもとより添付させない、送信させないなどできるかなと思います。
    サーバーログの結果によっては対策のできるものできないものがあるかと思いますので、今行っていただいているログのご確認よろしくお願いいたします。

    こんにちは

    upload_max_filesizeを超えているだけの場合には、正しくエラーハンドリングされるようです。

    post_max_sizeを超えている場合には、ハンドリングできずにぐるぐる回り続けるようです。

    私の環境ではpost_max_sizeを超えている場合を超えている場合にもサーバーからは
    {into: "#", status: "mail_sent", message: "ありがとうございます。メッセージは送信されました。"}
    と帰ってくるのですが、実際にはサーバー上で
    PHP Warning: POST Content-Length of 10210361 bytes exceeds the limit of 8388608 bytes in Unknown on line 0
    となり、POSTに失敗している様子です。

    ブラウザ側では

    Uncaught TypeError: Cannot read property 'dispatchEvent' of undefined
        at Object.wpcf7.triggerEvent (scripts.js?ver=4.9:361)
        at ajaxSuccess (

    となっていて、何かのオブジェクトか空のままっぽいですね・・・

    wpcf7_validate_fileフィルタにも辿り着けていないようなので、結論から言えばチェックは難しそうな・・・
    JavaScriptか何かのタイムアウトで無理やりエラー表示できるかもしれませんが、ちょっと分かりません。
    すいません。

    @munyagu さまにご検証いただきました内容を鑑みましてサーバー側で$_FILESのERRORを拾わなくてはならない様子ですね。
    しましたらアップロードしたあとにバルクで処理するよりも入力時にはじいたほうがいいと思います。

    以下をお試しいただけたらファイルサイズはファイル選択時に取得できると思いますので1024で割って安全マージンのとれる範囲を超えたら動作をさせない処理などはいかがでしょうか。

    
    <html>
    <head>
    <title>javascriptでサイズチェック</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body name="body" id="body">
    <input type="file" id="input_file"><br />
    <div id="div_message"></div>
    </body>
    </html>
    <script>
    //再利用のためにHTML要素を確保
    var obj_if = document.getElementById("input_file");
    var obj_dm = document.getElementById("div_message");
    //ファイルinputにイベントを追加(変更時動作
    obj_if.addEventListener("change", function(e){
    	//対象のファイルを確保
    	var file = e.target.files;
    	//複数の確保を前提とした確保方法なので今回は単体設定ですが
    	//一応個数分動作するように書きます
    	for(i=0;i<file.length;i++){
    	    obj_dm.innerHTML += "ファイルサイズ:" + file[i].size + "byte<br>";
    	    obj_dm.innerHTML += "ファイルタイプ:" + file[i].type;
    	}
    },false);
    </script>
    
    トピック投稿者 sugiura

    (@sugiura)

    munyaguさま

    ご検証いただきましてありがとうございます。
    サーバーの応答は私の場合、
    {into: "#", status: "validation_failed", message: "入力内容に問題があります。確認して再度お試しください。"}
    となり。サーバーの方は権限がなくログ確認ができておりません。
    いずれにしてもプラグインの期待動作が得られていないという感じでしょうか。
    ただ、ローカルだとUPLOAD_ERR_INI_SIZEあたりに引っかかるのか適切なハンドリングがされるようでした。
    応答は下記です。
    {into: "span.wpcf7-form-control-wrap.file-1", message: "ファイルのアップロード中にエラーが発生しました。", idref: "file-1"}

    msioさま

    確かに入力時に弾くのが確実なように思えました。
    記載頂きました内容を参考にさせていただきます。
    ありがとうございます。

    対応が少し後になりそうなのですが、確認後に再度ご報告させていただきます。
    皆さまありがとうございました。

    特に役立たない不親切なコードでもうしわけございませんでした。
    つまらない書き損じを直しておりましたら消えてしまいましてまた書き込ませていただきます…。

    レンタルサーバーの仕様によってはご利用の頻度もあるかと思い書き直しました。
    まだ不親切な点はあるかと思いますができるだけ条件にあわせたつもりのものを追記いたします。
    文中にもありますがPOSTサイズの上限もみてファイルの最大転送量よりすこし下めに上限設定されるのがよいかと思います。
    他要素と競合しないようであればウィジットなどに記述でも動くと思います。
    なにかの足しにいただければ幸いです。

    
    <!-- 静的要素 -->
    <html>
    <head>
    <title>javascriptでサイズチェック</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body name="body" id="body">
    <input type="file" id="input_file" multiple><br />
    <div id="div_message"></div>
    </body>
    </html>
    <!-- /静的要素 -->
    
    <!-- 基礎部分 -->
    <script>
    //HTML要素確保
    var obj_if = document.getElementById("input_file");
    var obj_dm = document.getElementById("div_message");
    //上限設定 10メガ
    //POSTサイズ上限でFILEMAXを凌駕されてしまうので
    //上限きっちりよりは他転送容量を差し引いて
    //安全マージンを確保してください。
    var $file_limit_size = (1024*1024)*10;
    
    //イベントを追加(ファイル選択変更時動作
    //この記述より実働部が下にあるなど読み込みタイミングによって動作しなくなるため
    //画面の要素が読み込み終えらえたなら開始する中にイベント追加を行います。
    //ファンクションが読み込まれていないタイミングで追加しようとしても
    //読み込まれていないファンクションを追加しません。
    //後付けでページに機能をつけるときには必要な操作になるかと思いまして。
    window.onload = function(){ obj_if.addEventListener("change",fleSizeCheckJS,false); }
    </script>
    <!-- /基礎部分 -->
    
    <!-- 表示テンプレート -->
    <div id="displaytemplete" style="display:none;">
    ファイル番号 [# filenumber #] ファイル名 [# filename #] ファイルサイズ [# filesize #]byte ファイルタイプ [# filetype #]
    </div>
    <!-- /表示テンプレート -->
    
    <script>
    //記述の自由度を高めるためあえて分けています。
    function fleSizeCheckJS(evetdata){
    	//取得と初期化
    	//成果物確保用
    	var $tempResult_fSCJS = "";
    	//ファイル情報を取得
    	var $file_data = evetdata.target.files;
    	//合計ファイルサイズ初期化
    	var $totalSize = 0;
    	//文字列形成テンプレート読み出し
    	var displaytemplete_text = document.getElementById("displaytemplete").innerHTML;
    
    	//ファイルの個数分循環
    	for($i=0;$i<$file_data.length;$i++){
    		//合計サイズ用集計
    		$totalSize += $file_data[$i].size;
    		//テンプレート文中要素を置き換え整形
    		//全部つなげていてきたないですが必要な個数分ちぎって使ってください。
    		$tempResult_fSCJS += displaytemplete_text.replace("[# filenumber #]",$i).replace("[# filename #]",$file_data[$i].name).replace("[# filesize #]",$file_data[$i].size).replace("[# filetype #]",$file_data[$i].type);
    	    $tempResult_fSCJS += "<br />";
    	}
    
    	//結果の反映
    	//結果表示要素に整形した文字列を代入 上書き初期化
    	obj_dm.innerHTML = $tempResult_fSCJS;
    	obj_dm.innerHTML += "<br />";
    	obj_dm.innerHTML += "合計:"+byteSizeExchange($totalSize);
    	obj_dm.innerHTML += "<br />";
    	if(($file_limit_size-$totalSize)<0){
    		obj_dm.innerHTML += "超過:"+byteSizeExchange($file_limit_size-$totalSize);
    	}else{
    		obj_dm.innerHTML += "余裕:"+byteSizeExchange($file_limit_size-$totalSize);
    	}
    	obj_dm.innerHTML += "<br />";
    }
    </script>
    
    <script>
    //人にやさしいサイズ表示
    function byteSizeExchange($sizedata){
    	var $tempResult_bSE = 0;
    	var $tempDimenstion = "";
    	if($sizedata<0){ $tempDimenstion = "-";$sizedata = Math.abs($sizedata); }
    
    	switch(true){
    	case $sizedata>(1024*1024*1024*1024):
    	$tempResult_bSE = parseInt(($sizedata/(1024*1024*1024*1024))*10)/10;
    	$tempResult_bSE += "TB";
    	break;
    	case $sizedata>(1024*1024*1024):
    	$tempResult_bSE = parseInt(($sizedata/(1024*1024*1024))*10)/10;
    	$tempResult_bSE += "GB";
    	break;
    	case $sizedata>(1024*1024):
    	$tempResult_bSE = parseInt(($sizedata/(1024*1024))*10)/10;
    	$tempResult_bSE += "MB";
    	break;
    	case $sizedata>(1024):
    	$tempResult_bSE = parseInt(($sizedata/(1024))*10)/10;
    	$tempResult_bSE += "KB";
    	break;
    	default:
    	$tempResult_bSE = $sizedata;
    	$tempResult_bSE += "Byte";
    	break;
    	}
    
    	return 	$tempDimenstion+$tempResult_bSE;
    }
    </script>
    
    トピック投稿者 sugiura

    (@sugiura)

    munyagu さま

    稼働環境はログを見れる権限がなかったのですがブラウザエラーは同様でした。
    どうも期待処理を通っていないようですが、プラグインのバージョンや環境でエラーハンドリングがなされたり少し違うようです。

    msio さま

    お返事が遅くなりまして申し訳ありません。
    非常に有用なコードを記載いただきありがとうございます!
    選択時にエラーを出して、念のためサイズ超過の際にはsubmitを非活性にしようかと思います。

    早急に解決策をご提示いただきましたのにご連絡が遅くなりましたこと、重ねてお詫び申し上げます。
    非常に助かりました。
    ありがとうございました!

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • トピック「contactform7 添付ファイルサイズ」には新たに返信することはできません。