将 ZIP 转换为 Blob
Converting ZIP to a Blob
在我们的 Ruby on Rails 应用程序中,我们有一个发送 ZIP 的控制器操作:
send_data File.read(zip_pathname), filename: zip_filename, type: 'application/zip'
我们使用 link 上的下载属性使其可下载,如下所示:
<%= link_to zip_download_path(@object), download: zip_filename do %>
<i class="fas fa-download fa-fw"></i> Download ZIP
<% end %>
效果很好,但可能需要 5-6 秒才能发生任何事情(由于 ZIP 大小)
为了防止用户再次单击 link 并显示正在发生的事情,我们尝试使用 AJAX 检索下载,然后将其转换为 Blob 并使用 FileReader 下载它:
const reader = new FileReader();
reader.onload = function(e) {
const anchor = document.createElement('a');
anchor.style.display = 'none';
anchor.href = e.target.result;
anchor.download = 'download';
anchor.click();
hideLoading();
}
$('[download]').on('click', function (e) {
e.preventDefault();
showLoading();
var download = $(this);
$.get(download.attr('href'), function (data) {
const blob = new Blob([data], { name: download.attr('download'), type: 'application/zip' });
reader.readAsDataURL(blob);
});
});
这成功显示了加载屏幕,然后下载了 ZIP 并再次隐藏了加载屏幕,除了 ZIP 作为下载错误返回,而不是像以前那样返回实际的 ZIP...这似乎是ZIP 到 Blob 是它失败的地方...
是否可以将 ZIP 转换为 Blob?上面的代码有什么问题吗?
正在看:e.target.result
内容是:
data:application/zip;base64,...
看起来它已经成功创建了数据...但是当我尝试在浏览器中打开它时 window 它没有显示任何内容...
如果您要通过 ajax 下载非文本文件(如 zip 文件),则必须指定一个二进制响应类型,在下面的示例中我将其设置为 blob,以便您在 ajax 响应中收到的数据将是一个 blob。
在锚点中创建并使用了一个 blob url,而不是庞大的数据 uri。
$.ajax({
url:download.attr('href'),
cache:false,
xhrFields:{
responseType: 'blob'
},
success: function(data){
var blobUrl = window.URL.createObjectURL(data);
const anchor = document.createElement('a');
anchor.style.display = 'none';
anchor.href = blobUrl;
anchor.download = 'download.zip';
anchor.click();
hideLoading();
},
error:function(){
}
});
jQuery 需要 3+ 才能工作。
只是想与任何想在不使用 jQuery3 的情况下执行此操作的人分享此内容...基于 Musa 发布的答案:
$('[download]').on('click', function (e) {
e.preventDefault();
showFullScreenLoading();
var $this = $(this);
var request = new XMLHttpRequest();
request.open('GET', $this.attr('href'), true);
request.responseType = 'blob';
request.onload = function (e) {
var data = request.response;
var blobUrl = window.URL.createObjectURL(data);
var downloadLink = document.createElement('a');
downloadLink.href = blobUrl;
downloadLink.download = $this.attr('download') || 'download';
downloadLink.click();
hideFullscreenLoading();
};
request.send();
});
在我们的 Ruby on Rails 应用程序中,我们有一个发送 ZIP 的控制器操作:
send_data File.read(zip_pathname), filename: zip_filename, type: 'application/zip'
我们使用 link 上的下载属性使其可下载,如下所示:
<%= link_to zip_download_path(@object), download: zip_filename do %>
<i class="fas fa-download fa-fw"></i> Download ZIP
<% end %>
效果很好,但可能需要 5-6 秒才能发生任何事情(由于 ZIP 大小)
为了防止用户再次单击 link 并显示正在发生的事情,我们尝试使用 AJAX 检索下载,然后将其转换为 Blob 并使用 FileReader 下载它:
const reader = new FileReader();
reader.onload = function(e) {
const anchor = document.createElement('a');
anchor.style.display = 'none';
anchor.href = e.target.result;
anchor.download = 'download';
anchor.click();
hideLoading();
}
$('[download]').on('click', function (e) {
e.preventDefault();
showLoading();
var download = $(this);
$.get(download.attr('href'), function (data) {
const blob = new Blob([data], { name: download.attr('download'), type: 'application/zip' });
reader.readAsDataURL(blob);
});
});
这成功显示了加载屏幕,然后下载了 ZIP 并再次隐藏了加载屏幕,除了 ZIP 作为下载错误返回,而不是像以前那样返回实际的 ZIP...这似乎是ZIP 到 Blob 是它失败的地方...
是否可以将 ZIP 转换为 Blob?上面的代码有什么问题吗?
正在看:e.target.result
内容是:
data:application/zip;base64,...
看起来它已经成功创建了数据...但是当我尝试在浏览器中打开它时 window 它没有显示任何内容...
如果您要通过 ajax 下载非文本文件(如 zip 文件),则必须指定一个二进制响应类型,在下面的示例中我将其设置为 blob,以便您在 ajax 响应中收到的数据将是一个 blob。
在锚点中创建并使用了一个 blob url,而不是庞大的数据 uri。
$.ajax({
url:download.attr('href'),
cache:false,
xhrFields:{
responseType: 'blob'
},
success: function(data){
var blobUrl = window.URL.createObjectURL(data);
const anchor = document.createElement('a');
anchor.style.display = 'none';
anchor.href = blobUrl;
anchor.download = 'download.zip';
anchor.click();
hideLoading();
},
error:function(){
}
});
jQuery 需要 3+ 才能工作。
只是想与任何想在不使用 jQuery3 的情况下执行此操作的人分享此内容...基于 Musa 发布的答案:
$('[download]').on('click', function (e) {
e.preventDefault();
showFullScreenLoading();
var $this = $(this);
var request = new XMLHttpRequest();
request.open('GET', $this.attr('href'), true);
request.responseType = 'blob';
request.onload = function (e) {
var data = request.response;
var blobUrl = window.URL.createObjectURL(data);
var downloadLink = document.createElement('a');
downloadLink.href = blobUrl;
downloadLink.download = $this.attr('download') || 'download';
downloadLink.click();
hideFullscreenLoading();
};
request.send();
});