Javascript 使用 jQuery AJAX 下载二进制文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33902299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using jQuery AJAX to download a binary file
提问by edwardsmarkf
I am attempting to use jQuery AJAX to download a binary audio file.
我正在尝试使用 jQuery AJAX 下载二进制音频文件。
Normally I would just issue a command like this:
通常我只会发出这样的命令:
windows.location.href = 'http://marksdomain(dot)com/audioFile.wav' ;
However, recently our server has been waiting too long to respond, and I get a nasty gateway timeout message.
但是,最近我们的服务器等待响应的时间太长了,我收到了令人讨厌的网关超时消息。
It has been suggested that I use jQuery AJAX instead, which makes sense since then i would have more control over the timeout.
有人建议我改用 jQuery AJAX,从那时起我就可以更好地控制超时。
Here is the code i have played with so far:
这是我迄今为止玩过的代码:
$.ajax({
url: 'http://marksdomain(dot)com/audioFile.wav',
timeout: 999999,
dataType: 'binary',
processData: false, // this one does not seem to do anything ?
success: function (result) {
console.log(result.length);
},
error: function (result, errStatus, errorMessage) {
console.log(errStatus + ' -- ' + errorMessage);
}
};
When I omit the "dataType", the binary file is coming through about three times larger than it actually is on the server. However, when i make the dataType equal to "binary", AJAX throws an error:
当我省略“dataType”时,二进制文件的大小大约是服务器上实际大小的三倍。但是,当我使 dataType 等于“binary”时,AJAX 会抛出错误:
"No conversion from text to binary"
From some earlier posts, it sounds as if jQuery AJAX cannot handle binary files in this manner.
从一些较早的帖子中,听起来好像 jQuery AJAX 无法以这种方式处理二进制文件。
I did discover Delivery.jswhich actually works quite well for what I am attempting, but I would rather not use a node solution if possible.
我确实发现Delivery.js对于我正在尝试的内容实际上非常有效,但如果可能的话,我宁愿不使用节点解决方案。
Any suggestions?
有什么建议?
回答by Brandon
Just use XHR directly. This example is taken from MDN:
直接用XHR就行了。这个例子取自MDN:
var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
oReq.onload = function(oEvent) {
var arrayBuffer = oReq.response;
// if you want to access the bytes:
var byteArray = new Uint8Array(arrayBuffer);
// ...
// If you want to use the image in your DOM:
var blob = new Blob([arrayBuffer], {type: "image/png"});
var url = URL.createObjectURL(blob);
someImageElement.src = url;
// whatever...
};
oReq.send();
回答by MattE
You can set up an $.ajax transport to modify the settings as mentioned here: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
您可以设置 $.ajax 传输来修改此处提到的设置:http: //www.henryalgus.com/reading-binary-files-using-jquery-ajax/
// use this transport for "binary" data type
$.ajaxTransport("+binary", function (options, originalOptions, jqXHR) {
// check for conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))) {
return {
// create new XMLHttpRequest
send: function (headers, callback) {
// setup all variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
async = options.async || true,
// blob or arraybuffer. Default is blob
dataType = options.responseType || "blob",
data = options.data || null,
username = options.username || null,
password = options.password || null;
xhr.addEventListener('load', function () {
var data = {};
data[options.dataType] = xhr.response;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, async, username, password);
// setup custom headers
for (var i in headers) {
xhr.setRequestHeader(i, headers[i]);
}
xhr.responseType = dataType;
xhr.send(data);
},
abort: function () {
jqXHR.abort();
}
};
}
});
and then make your ajax call:
然后让你的ajax调用:
return $.ajax({
url: url,
method: 'GET',
dataType: 'binary',
processData: 'false',
responseType: 'arraybuffer',
headers: { 'X-Requested-With': 'XMLHttpRequest' }
}).then(function (response) {
var data = new Uint8Array(response);
//do something with the data
return data;
}, function (error) {
alertify.error('There was an error! Error:' + error.name + ':' + error.status)
});
回答by MattE
If you must use jQuery, you can use $.ajaxSetup()
to modify low-level settings.
如果必须使用jQuery,可以使用$.ajaxSetup()
修改低级设置。
Example:
例子:
// Set up AJAX settings for binary files:
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
if (settings.dataType === 'binary') {
settings.xhr().responseType = 'arraybuffer';
}
}
})
// Make the actual call:
let result = await $.ajax({
url: '/api/export/data',
type: 'GET',
contentType: 'application/json',
dataType: 'binary',
processData: false,
headers: {
token: localStorage.token,
},
});