![](/img/trans.png)
[英]jQuery ajax() returning json object to another function on success causes error
[英]jQuery .ajax() calls the error function instead of success if the XHR response is an ArrayBuffer representing a JSON object with an error property
上下文:我正在嘗試通過進度條和錯誤處理來實現Ajax下載。 前端向后端發出請求,后端以下載文件或JSON對象形式的錯誤作為響應。
問題:我使用的是自定義xhr,其中responseType
設置為arraybuffer
。 這使我可以為文件創建一個Blob,然后將其用於顯示下載內容。 如果后端使用JSON對象響應,我可以正確地檢測到它,將其轉換為字符串,然后將其解析為本地Object
。 但是,如果該Object
包含一個名為error
的屬性,我將在整個應用程序中使用它,則jQuery調用error()
而不是success()
,並傳遞一個參數,即error
屬性的值。
到底他媽發生了什么? 我已將dataType: false
設置為避免對數據進行任何處理,但是盡管dataType
設置和響應標頭設置為application/octet-stream
,並且確定該對象有錯誤,但jQuery似乎正在解析arraybuffer。屬性,需要調用error()
函數。
如何在不更改后端的情況下避免這種行為? 另一種實現方式可以是將responseType
保留為文本,然后在文本成為文件時將其轉換為Blob,但我永遠無法使其正常工作。
$.ajax({
url: "?download",
method: "POST",
data: {path: this.path, names: names},
dataType: false,
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
myXhr.responseType = "arraybuffer"
myXhr.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percent = Math.round(e.loaded / e.total * 100);
var text = dir.formatSize(e.loaded, true) + "/" + dir.formatSize(e.total, true)
$("#dl-progress-bar").css("width", percent + "%");
$("#dl-progress-text").text(text)
}
})
return myXhr;
},
success: function(data) {
$("#dl-progress").hide()
$("#dl-progress-bar").css("width", "0")
$("#dl-progress-text").html(" ")
var bufView = new Uint8Array(data);
//Check if the arraybuffer is actually JSON, starting with {"
if (bufView[0] == 123 && bufView[1] == 34 && bufView.length < 200) {
var string = decodeURIComponent(escape(String.fromCharCode.apply(null, Array.prototype.slice.apply(bufView))))
try {
var json = JSON.parse(string)
if (json.success === false && json.error) {
this.error(json.error)
return
}
}
catch (e) {}
}
if (data != null && navigator.msSaveBlob)
return navigator.msSaveBlob(new Blob([data], { type: type }), name)
var a = $("<a style='display: none;'/>")
var blob = new Blob([data], {type: "application/octet-stream"})
var url = window.URL.createObjectURL(blob)
a.attr("href", url)
a.attr("download", filename)
$("body").append(a)
a[0].click()
setTimeout(function() {
window.URL.revokeObjectURL(url);
a.remove()
}, 0)
},
error: function(req, status, error) {
debugger
$("#dl-progress").hide()
$("#dl-progress-bar").css("width", "0")
$("#dl-progress-text").html(" ")
this.ajaxError(req, status, error)
}.bind(this)
})
問題是我沒有bind()
我的成功函數,所以它調用了xhr對象的this.error()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.