6

サーバー上で zip ファイルを作成し、それをブラウザーに返す高価なフォーム アクションがあります。

<form action='/download' method='post'>

<input type='submit' value='download'/>

</form>

ユーザーがボタンを繰り返し押さないように、ボタンのクリック時にページをブロックしたい。

ただし、フォームが返された後にページのブロックを解除したいと考えています。

フォームが正常に完了したときにイベントをトリガーするにはどうすればよいですか?

(フォームを ajax 送信に変更することでこれをトリガーできることはわかっていますが、ファイルの保存ダイアログは表示されません...)

助言がありますか?

ありがとう

4

4 に答える 4

5

AJAX を使用せずにこれを処理できる 1 つの方法は、フォームのコンテンツをiframe要素に送信することです。それ以降の送信を無効にする onsubmit 関数をフォームにアタッチし、iframe に onload 関数をアタッチすると、ユーザーがフォームを複数回送信することを無効にできるはずです。

HTML の例:

<form action="/download" method="post" target="downloadFrame" onsubmit="return downloadFile();">
  <input type="submit" value="download" />
</form>
<iframe style="width: 0px; height: 0px;" scrolling="no" frameborder="0" border="0" name="downloadFrame" onload="downloadComplete();"></iframe>

JavaScript の例:

var downloading = false;
function downloadFile() {
    var isDownloading = downloading;
    downloading = true;
    return !isDownloading;
}
function downloadComplete() {
    downloading = false;
}
于 2012-11-23T13:07:15.617 に答える
0

ブラウザ自体でポスト リターンを検出する方法はまだ見つかっていないようですが、AJAX を使用する別の可能性があります。ただし、もう少し複雑です。

<script type="text/javascript">
    $(function () {
        $('#submitbtn').click (function () {
            window.setTimeout (dldone, 100);
            return true;
        });

        function dldone () {
            $.get ("/downloadstatus?rand="+$('#rand').val (), function (data) {
                if (data == 'done') {
                    // data generation finished, do something
                } else {
                   window.setTimeout (dldone, 100);
                }
            });
        }
    });
</script>
<form action="/generatedata" method="post">
    <input type="hidden" id="rand" value="[RANDOMVALUE]">
    <input type="submit" id="submitbtn" value="Download Data">
</form>

サーバーでは、データ生成が完了したときに通知するために、プロセス間通信を行う必要があります。すでにデータベースがあるので、次のようにしました。

public function downloadstatusAction () {
    if ($this->db->fetchOne ("SELECT rand FROM dlstatus WHERE rand = ?", (int) $_GET["rand"])) {
        $db->delete ("dlstatus", array ("rand = ?" => (int) $_GET["rand"]));
        print "done";
    } else {
        print "loading";
    }
}

public function generatedataAction () {
    // generate data
    $this->db->insert ("dlstatus", array ("rand" => (int) $_POST["rand"]));
    // output data
}

これを行うためのよりエレガントな方法があると確信していますが、アイデアはわかります。これは、私がテストしたすべてのブラウザーで問題なく動作するようです。

于 2013-08-06T14:00:56.283 に答える
0

私はこれを使用しました:

function generatePdfZipViaWS_ajax(theUrl) {

    //=========================
    // testé avec Chrome 37.0.2062.124 m, Firefox  32.0.3
    // ça block avec IE9 à cause du xmlHttp.overrideMimeType
    //=========================
    var xmlHttp = new XMLHttpRequest();

    var alert = document.getElementById("alertError");
    block_UI();

    var url = "undefined";

    xmlHttp.open("GET", theUrl, true);
    xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xmlHttp.overrideMimeType("application/octet-stream");
    xmlHttp.responseType = "blob";

    xmlHttp.onload = function(oEvent) {
        if (xmlHttp.status == 200) {

            deblock_UI();
            // a mettre apres un certain temps:  window.URL.revokeObjectURL(url);

        } else {
            alert.style.display = "block";
            deblock_UI();

            //  console.log("Error " + xmlHttp.status + " occurred downloading your file.<br \/>");
        }
    };

    xmlHttp.onreadystatechange = function() {

        if (xmlHttp.readyState == xmlHttp.DONE) {

            if (xmlHttp.status == 200) {

                var contentDisposition = xmlHttp.getResponseHeader("Content-Disposition");
                var type = xmlHttp.getResponseHeader("Content-Type");

                var reponseType = xmlHttp.responseType;

                var pos1 = contentDisposition.indexOf("archive");
                var pos2 = contentDisposition.lastIndexOf(".zip") + 4;
                var fileName = contentDisposition.substring(pos1, pos2);

                if (fileName === null) {
                    fileName = "archivexxxxxxxxxxxxxx.zip";
                }

                console.log("fileName:" + fileName);

                var blob = xmlHttp.response;
                url = URL.createObjectURL(blob);

                var a = document.createElement('a');
                a.style = "display: none";
                a.href = url;
                a.download = fileName;
                a.type = type;
                document.body.appendChild(a);
                a.click();
                //a.delete();

                deblock_UI();

            } else {

                var msg =" Une erreur "  + xmlHttp.status +" est apparue pendant que votre demande était traitée.\n"

                msg = msg + "Merci de réessayer plus tard!";

                alert.innerHTML = msg;
                alert.style.display = "block";

                deblock_UI();
                console.log(msg);
            }
        }
    };
    xmlHttp.send();
}
于 2014-11-28T14:00:03.103 に答える