下载数据 URL 文件

我正在考虑制作一个完全基于 JavaScript 的 zip/unzip 工具,任何人都可以从浏览器访问它。他们可以直接把压缩文件拖到浏览器里,这样就可以下载里面的所有文件了。它们还可以通过拖动单个文件来创建新的 zip 文件。

我知道最好在服务器端做,但这个项目只是为了一点乐趣。

如果我充分利用各种可用的方法,将文件拖放到浏览器中应该很容易。(Gmail 风格)

编码/解码应该没问题。我看过一些3压缩包库,所以我确信我应该没问题。

我的问题是在最后下载文件。

window.location = 'data:jpg/image;base64,/9j/4AAQSkZJR....'

这在 Firefox 中可以很好地工作,但在 Chrome 中就不行了。

我可以嵌入的图像文件只是罚款铬使用 <img src="data:jpg/image;ba.." />,但文件将不一定是图像。它们可以是任何形式。

有人能想到别的解决办法或者变通办法吗?

553069 次浏览

想法:

  • 尝试 <a href="data:...." target="_blank">(未测试)

  • 使用 下载代替数据 URL (对 IE 也同样适用)

你的问题本质上归结为“不是所有的浏览器都支持这个”。

你可以尝试一个解决方案,并从一个 Flash 对象提供解压缩文件,但那样你将失去纯粹的 JS (无论如何,我不确定你目前是否可以“拖动文件到浏览器”没有一些类型的 Flash 解决方案-这是一个 HTML5功能可能

有几种解决方案,但它们依赖于 HTML5,而且还没有在一些浏览器中完全实现。下面的例子在 Chrome 和 Firefox 中进行了测试(部分工作)。

  1. 画布示例 ,保存为文件支持。只需将 document.location.href设置为数据 URI。
  2. 锚点下载示例 。它使用 <a href="your-data-uri" download="filename.txt">指定文件名。

如果你还想给文件一个建议的名称(而不是默认的“下载”) ,你可以在 Chrome,Firefox 和一些 IE 版本中使用以下命令:

function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}

下面的例子说明了它的用途:

downloadURI("data:text/html,HelloWorld!", "helloWorld.txt");

想要分享我的经验,并帮助有人坚持下载不工作在火狐和更新2014年的答案。 下面的代码片段将同时适用于 Firefox 和 chrome,它将接受一个文件名:

  // Construct the <a> element
var link = document.createElement("a");
link.download = thefilename;
// Construct the uri
var uri = 'data:text/csv;charset=utf-8;base64,' + someb64data
link.href = uri;
document.body.appendChild(link);
link.click();
// Cleanup the DOM
document.body.removeChild(link);

下面是我在火狐和 Chrome 上测试过的一个纯 JavaScript 解决方案,但没有在 Internet Explorer 上测试过:

function downloadDataUrlFromJavascript(filename, dataUrl) {


// Construct the 'a' element
var link = document.createElement("a");
link.download = filename;
link.target = "_blank";


// Construct the URI
link.href = dataUrl;
document.body.appendChild(link);
link.click();


// Cleanup the DOM
document.body.removeChild(link);
delete link;
}

到目前为止,跨浏览器的解决方案已经出现:

下载-> 需要闪存

在 IE10和 IE11中进行了测试,对我来说不起作用。需要一个 servlet 和一些自定义。(错误检测导航器。我必须将 IE 设置为兼容模式来进行测试,在 servlet 中设置默认字符集,JavaScript 选项对象使用正确的 servlet 路径来设置绝对路径...)对于非 IE 浏览器,它在同一个窗口中打开文件。

Js-> http://danml.com/download.html另一个类似但未经测试的库。声称是纯 JavaScript,不需要 servlet 或 Flash,但不能在 IE < = 9上工作。

对于任何有 IE 问题的人:

dataURItoBlob = function(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/png'});
}


var blob = dataURItoBlob(uri);
window.navigator.msSaveOrOpenBlob(blob, "my-image.png");

这段代码最初是由@Yetti 在 这个答案上提供的(另一个问题)。

结合@owencm 和@Chazt3n 的答案,该功能将允许从 IE11、 Firefox 和 Chrome 下载文本。(对不起,我没有访问 Safari 或 Opera 的权限,但是如果您尝试并且它可以工作,请添加评论。)

initiate_user_download = function(file_name, mime_type, text) {
// Anything but IE works here
if (undefined === window.navigator.msSaveOrOpenBlob) {
var e = document.createElement('a');
var href = 'data:' + mime_type + ';charset=utf-8,' + encodeURIComponent(text);
e.setAttribute('href', href);
e.setAttribute('download', file_name);
document.body.appendChild(e);
e.click();
document.body.removeChild(e);
}
// IE-specific code
else {
var charCodeArr = new Array(text.length);
for (var i = 0; i < text.length; ++i) {
var charCode = text.charCodeAt(i);
charCodeArr[i] = charCode;
}
var blob = new Blob([new Uint8Array(charCodeArr)], {type: mime_type});
window.navigator.msSaveOrOpenBlob(blob, file_name);
}
}


// Example:
initiate_user_download('data.csv', 'text/csv', 'Sample,Data,Here\n1,2,3\n');

function download(dataurl, filename) {
const link = document.createElement("a");
link.href = dataurl;
link.download = filename;
link.click();
}


download("data:text/html,HelloWorld!", "helloWorld.txt");

或:

function download(url, filename) {
fetch(url)
.then(response => response.blob())
.then(blob => {
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
})
.catch(console.error);
}


download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");

这可以解决100% 完全 只使用 HTML。只需设置 href属性为 "data:(mimetypeheader),(url)"。例如..。

<a
href="data:video/mp4,http://www.example.com/video.mp4"
target="_blank"
download="video.mp4"
>Download Video</a>

工作示例: < strong > JSFiddle Demo

因为我们使用 DataURL,所以允许我们设置 imetype,它指示要下载的数据类型。文件:

数据 URL 由四部分组成: 前缀(Data:)、表示数据类型的 MIME 类型、非文本的可选 base64标记和数据本身。(来源: 数据 URL)

组件:

  • 链接标签。
  • href="data:video/mp4,http://www.example.com/video.mp4": 这里我们将链接设置为 data:,头部预先配置为 video/mp4。接下来是头部 imetype。也就是说,对于一个 .txt文件,它应该是 text/plain。然后用逗号把它和我们要下载的链接分开。
  • target="_blank": 这表示应该打开一个新的选项卡,它不是必需的,但它有助于引导浏览器到所需的行为。
  • download: 这是您正在下载的文件的名称。

如果你只需要一个实际的下载操作,比如你把它绑定到一个按钮上,当你点击它的时候,它就会立刻生成 URL (例如在 Vue 或者 React 中) ,你可以做一些简单的事情:

const link = document.createElement('a')
link.href = url
link.click()

在我的例子中,该文件已经正确命名,但是如果需要,您可以使用 filename来设置它。

export const downloadAs = async (url: string, name: string) => {
const blob = await axios.get(url, {
headers: {
'Content-Type': 'application/octet-stream',
},
responseType: 'blob',
});
const a = document.createElement('a');
const href = window.URL.createObjectURL(blob.data);
a.href = href;
a.download = name;
a.click();
};

您可以使用一个干净的代码解决方案,在一个常量中通知您的 url,并将其设置为 open 方法的参数,而不是在对象窗口中。

const url = "file url here"


window.open(url)