IE (含 IE11) 下使用 AJAX (FormData + XMLHttpRequest) 或 iframe 方式上傳圖片,後端返回 JSON ({"success":true, "url":"..."}),前端預期進入 success 回調,但 IE 彈出「打開/保存」下載對話框,下載內容為返回的 JSON 文本。
Content-Type: application/json** 的響應,**不識別為可執行腳本**,視為「文件下載」onload/successtext/html 內容視為下載Content-Type: text/html (最簡單、兼容性最好)
// PHP
header('Content-Type: text/html; charset=utf-8');
echo json_encode(['success' => true, 'url' => $url]);
// Java Spring
@PostMapping(value = "/upload", produces = "text/html;charset=UTF-8")
@ResponseBody
public String upload(...) {
return JSON.toJSONString(result);
}
// Node.js Express
res.set('Content-Type', 'text/html; charset=utf-8');
res.send(JSON.stringify(result));
// C# ASP.NET
Response.ContentType = "text/html; charset=utf-8";
Response.Write(JsonConvert.SerializeObject(result));
原理:IE 將 text/html 視為文檔,在 iframe/XHR 中正常載入並觸發回調,前端 JSON.parse(responseText) 即可獲取數據。
FormData + fetch / XMLHttpRequest 並設置 responseType = 'text'
var formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('/upload', {
method: 'POST',
body: formData,
credentials: 'include' // 攜帶 Cookie
})
.then(response => response.text()) // 強制按文本讀取
.then(text => {
var result = JSON.parse(text);
// 處理結果
});
現代瀏覽器支援良好,IE 需 Polyfill (fetch、Promise、FormData)。
text/html 響應
// HTML
// JS
$('#uploadForm').on('submit', function() {
$('#uploadIframe').on('load', function() {
var responseText = this.contentDocument.body.innerText;
var result = JSON.parse(responseText);
// 處理結果
});
});
iframe 的 load 事件在 IE 中同樣要求響應 Content-Type: text/html。
Content-Disposition: inline (輔助)
header('Content-Disposition: inline; filename="response.json"');
header('Content-Type: application/json; charset=utf-8');
嘗試告訴 IE「內聯顯示」,但效果不穩定,**不推薦作為主方案**。
function uploadFile(file, url, callback) {
var formData = new FormData();
formData.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function() {
if (xhr.status === 200) {
try {
// 兼容 text/html 和 application/json
var result = JSON.parse(xhr.responseText);
callback(null, result);
} catch (e) {
callback(new Error('響應非合法 JSON: ' + xhr.responseText));
}
} else {
callback(new Error('上傳失敗: ' + xhr.status));
}
};
xhr.send(formData);
}
核心修復:後端響應頭設置 Content-Type: text/html; charset=utf-8。這是解決 IE AJAX/iframe 文件上傳回調異常的**標準、最穩定、零前端改動**方案。現代專案建議全棧遷移至 fetch + 標準 JSON 響應,逐步淘汰 IE 支援。