首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JSP 頁面彈出非模態對話框並防重複提交實作

     編輯:程式設計綜合問答

傳統 form.submit() 會導致頁面跳轉或封鎖 UI。若需「彈出對話框不阻擋原頁操作」且「防重複點擊同一筆資料」,可採用 隱藏 iframe 當表單目標 搭配 前端狀態旗標 實現。

核心架構


<!-- 1. 頁面底部放置隱藏 iframe 作為表單提交目標 -->
<iframe id="hiddenFrame" name="hiddenFrame" style="display:none;"></iframe>

<!-- 2. 表單 target 指向 iframe -->
<form id="exportForm" action="export.do" method="post" target="hiddenFrame">
    <input type="hidden" name="cmd" value="expToExcel">
    <input type="hidden" name="id" id="exportId">
</form>

<!-- 3. 列表按鈕觸發 JS -->
<input type="button" value="導出協議" onclick="expToExcel('${record.id}')" class="button_ellipse">

JavaScript 邏輯


var lastExportedId = null; // 全域旗標記錄最後導出的 ID

function expToExcel(recordId) {
    // 防重複:同一 ID 短時間內不重複送出
    if (lastExportedId === recordId) {
        alert("請不要重複選擇!");
        return false;
    }

    // 可選:加入時間窗防抖(如 2 秒內不重複)
    // if (Date.now() - lastExportTime < 2000) return;

    lastExportedId = recordId;
    document.getElementById('exportId').value = recordId;
    document.getElementById('exportForm').submit();

    // iframe 載入完成後可選清除旗標,允許再次導出
    // 需配合 iframe onload 事件
}

進階:iframe 載入監聽與使用者回饋


var iframe = document.getElementById('hiddenFrame');
iframe.onload = function() {
    try {
        var doc = iframe.contentDocument || iframe.contentWindow.document;
        var response = doc.body.innerText;
        // 解析後端回應(如 JSON),顯示成功/失敗提示
        console.log('Export response:', response);
    } catch (e) {
        // 跨域或解析失敗靜默處理
    }
    // 可選:延遲清除旗標
    // setTimeout(() => { lastExportedId = null; }, 5000);
};

替代現代方案:Fetch + Blob 下載

若後端支援回傳檔案串流,可完全移除 iframe,改用 fetch() 取得 Blob 並觸發下載,體驗更佳:


async function expToExcelModern(recordId) {
    if (lastExportedId === recordId) return alert("請不要重複選擇!");
    lastExportedId = recordId;

    try {
        const res = await fetch('export.do', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: `cmd=expToExcel&id=${recordId}`
        });
        const blob = await res.blob();
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `agreement_${recordId}.xls`;
        a.click();
        URL.revokeObjectURL(url);
    } catch (e) {
        console.error(e);
        alert('導出失敗');
    }
}

方案比較

方案相容性體驗複雜度
隱藏 iframeIE6+ 完美無進度條、難處理錯誤低
Fetch + Blob現代瀏覽器可顯示進度、優雅錯誤處理中
AJAX + 檔案下載連結廣泛支援需後端配合生成暫存檔中高

根據專案瀏覽器支援需求選擇方案;舊系統維護推薦 iframe,新專案優先採用 Fetch 模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved