在前端開發中,若需透過 AJAX 直接讀取或傳送二進位資料(如圖片、檔案串流),預設的 XMLHttpRequest 行為會嘗試以文字方式解碼,導致資料損壞。本文說明如何正確設定請求標頭與回應處理,確保二進位資料完整傳輸。
關鍵在於呼叫 overrideMimeType() 強制瀏覽器將回應視為原始位元組流,並使用 xhr.response(而非 responseText)取得資料:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var binaryData = xhr.response; // 取得 ArrayBuffer 或 Blob
// 後續處理 binaryData,例如建立 Blob URL 顯示圖片
}
};
xhr.open("GET", url, true);
// 關鍵設定:阻止瀏覽器嘗試解碼
xhr.overrideMimeType("text/plain; charset=x-user-defined");
xhr.send(null);
說明:charset=x-user-defined 讓瀏覽器將每個位元組映射為 Unicode 碼位 U+0000 至 U+00FF,保留原始位元組值。
發送前需將字串中的高位元清零(只保留低 8 位),可擴充 XMLHttpRequest.prototype 加入 sendAsBinary 方法:
XMLHttpRequest.prototype.sendAsBinary = function(dataStr) {
function byteValue(x) {
return x.charCodeAt(0) & 0xff; // 取低 8 位
}
var ords = Array.prototype.map.call(dataStr, byteValue);
var ui8a = new Uint8Array(ords);
this.send(ui8a.buffer); // 發送 ArrayBuffer
};
// 使用範例
var binaryData = "..."; // 你的二進位字串資料
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.sendAsBinary(binaryData);
現代瀏覽器建議直接使用 xhr.send(blob) 或 xhr.send(arrayBuffer),但上述相容寫法在舊版瀏覽器仍具參考價值。