首页 > 解决方案 > 通过浏览器中的 Javascript 在 iOS 上保存 Zip 文件

问题描述

几年前,我创建了一个应用程序kodeWeave。现在kodeWeave使用一个名为JSZip的 JavaScript 库,用于在客户端创建和下载 .zip 文件。

但是,我无法在我的 iPhone 上使用 JSZip 下载 zip 文件,但如果 zip 文件位于像Github这样的服务器上,我实际上可以在我的 iPhone 上下载 zip 文件。

起初我以为它可能只是 Chrome 浏览器,但是,我用其他浏览器进行了测试,例如 Safari、Firefox、Edge、Dolphin Browser 和 MyMedia。所有人都会打开一个新的 blob 或空白选项卡,但仅此而已,它只是位于一个什么都不做的空白选项卡上。

因为我可以在服务器上下载 zip 文件,所以这个问题与 JSZip 的编程方式特别相关。所以我的问题分为两部分。

1) 有谁知道如何用 JSZip 解决这个问题?

2) 封装问题 1 根本不是一个选项(至少在 Apple 改进他们的技术之前。有没有人知道一种将 zip 文件动态保存到服务器的方法,类似于 JSZip 通过 blob 保存 zip 文件的方式?

标签: javascriptiosdownloadzipjszip

解决方案


实际问题不在 JSZip 中,而是在示例中所示的FileSaver.js中。

在 FileSaver README 中有一个针对 iOS的警告。

saveAs 必须在用户交互事件中运行,例如onTouchDownonClicksetTimeout将阻止 saveAs 触发。由于 iOS saveAs 在新窗口中打开而不是下载的限制,如果您想修复此问题,请告诉 Apple 此错误对您的影响。

另请注意其他浏览器支持及其对您的应用程序的限制。

  1. 这不是 JSZip 的问题。由于系统限制,无法在 iOS 中修复 FileSaver。 我建议您将临时 zip 文件上传到后端并向最终用户提供下载链接。

怎么做?我修改了 JSZip 官方网站上的示例。作为 HTTP 客户端,我更喜欢axios,但你可以使用 vanilla XMLHttpRequest 或 fetch。

var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images");
img.file("smile.gif", imgData, {base64: true});

zip.generateAsync({type:"blob"})
    .then(function(content) {
        const file = new FormData();
        file.append("blob", content)

        axios.put('/upload/server', file, {})
            .then(function (res) {
              // done
              console.info('Uploaded')
            })
            .catch(function (err) {
              console.error('Failed due', err.message);
            });
});
  1. 从 2012 年 [原文如此!] 和Bug 167341 开始,打开了一些错误,并提出了一个补丁建议Bug 102914。我相信社区可以推动这个修复发生。

推荐阅读