傳統 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">
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 事件
}
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);
};
若後端支援回傳檔案串流,可完全移除 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('導出失敗');
}
}
| 方案 | 相容性 | 體驗 | 複雜度 |
|---|---|---|---|
| 隱藏 iframe | IE6+ 完美 | 無進度條、難處理錯誤 | 低 |
| Fetch + Blob | 現代瀏覽器 | 可顯示進度、優雅錯誤處理 | 中 |
| AJAX + 檔案下載連結 | 廣泛支援 | 需後端配合生成暫存檔 | 中高 |
根據專案瀏覽器支援需求選擇方案;舊系統維護推薦 iframe,新專案優先採用 Fetch 模式。