在 AJAX 尚未普及或不支援 FormData 的舊版瀏覽器時代,利用隱藏 <iframe> 作為表單提交目標(target 屬性),是實現「無刷新上傳」的經典技巧。本文提供完整的 MVC 實作範例,包含前端表單、JavaScript 回呼與後端處理邏輯。
<div id="uploadwindow" style="display: none;">
<form action="/ShopActivitys/ImportActivityItems"
id="form1" name="form1"
enctype="multipart/form-data"
method="post"
target="hidden_frame">
<table style="width: 300px;">
<tr>
<td style="width: 80px; display: block;">選擇檔案:</td>
<td>
<input type="file" id="file" name="activityitemsfile" />
</td>
</tr>
</table>
<input type="submit" value="上傳檔案" />
<!-- 隱藏 iframe 作為提交目標 -->
<iframe name='hidden_frame' id="hidden_frame" style='display: none'></iframe>
</form>
</div>
關鍵點:
enctype="multipart/form-data":檔案上傳必須。target="hidden_frame":指定提交目標為同頁隱藏 iframe,頁面不會跳轉。name="activityitemsfile":後端 Request.Files["activityitemsfile"] 取檔案時的鍵名。後端處理完成後,透過 Response.Write 輸出一段 <script> 呼叫父視窗的回呼函數:
var UploadFun = {
CallBack: function (msg) {
$.messager.alert('上傳檔案', msg, 'info'); // 使用 EasyUI 或自訂提示
}
};
public void ImportActivityItems()
{
string error = "導入成功";
try
{
var file = Request.Files["activityitemsfile"];
var savePath = Server.MapPath("/Upload/活動鏈接數據/");
if (!Directory.Exists(savePath))
Directory.CreateDirectory(savePath);
// 以時間戳避免檔名衝突
string fullName = savePath + DateTime.Now.ToFileTime() + file.FileName;
file.SaveAs(fullName);
}
catch (Exception ex)
{
Logger.Error(ex.ToString());
error = "導入過程中發生錯誤,請重試";
}
// 輸出 script 呼叫父頁面回呼
Response.Write("<script type=\"text/javascript\"> parent.UploadFun.CallBack(\"" + error + "\")</script>");
}
若專案環境支援 HTML5,強烈建議改用 FormData + XMLHttpRequest / fetch / jQuery $.ajax 實現真正的非同步上傳,優勢在於:
xhr.upload.onprogress)。// 現代寫法範例
$('#file').on('change', function() {
var formData = new FormData();
formData.append('activityitemsfile', this.files[0]);
$.ajax({
url: '/ShopActivitys/ImportActivityItems',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(res) { $.messager.alert('結果', res); },
error: function() { $.messager.alert('錯誤', '上傳失敗'); }
});
});
IFrame 無刷新上傳是相容舊瀏覽器的實用技巧,核心在於 form.target = iframe.name 與後端輸出 parent.callback()。新專案請優先採用 FormData 非同步上傳,體驗與維護性更佳。