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

IE AJAX 文件上傳回調觸發下載提示:Content-Type 設置為 text/html 解決

     編輯:程式設計綜合問答

問題現象

IE (含 IE11) 下使用 AJAX (FormData + XMLHttpRequest) 或 iframe 方式上傳圖片,後端返回 JSON ({"success":true, "url":"..."}),前端預期進入 success 回調,但 IE 彈出「打開/保存」下載對話框,下載內容為返回的 JSON 文本。

根因分析

  • IE 對 **Content-Type: application/json** 的響應,**不識別為可執行腳本**,視為「文件下載」
  • Chrome/Firefox 正確處理 JSON 響應並觸發 onload/success
  • iframe 載入響應時,IE 更傾向將非 text/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)。

方案三:傳統 iframe 上傳 + 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 支援。

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