无需用户交互即可浏览器下载/保存文件

时间:2014-01-15 09:50:21

标签: javascript browser download

我需要创建一个基于浏览器的小应用程序,帮助用户下载/保存,并可能打印到默认打印机,来自我们无法控制的网络服务器中的大量文件(但我们事先已经拥有了所有URI)。 / p>

这些文件隐藏在“单点登录”(SSO)之后,只能通过浏览器执行,并且需要用户。因此,它必须是基于浏览器的解决方案,我们捎带到SSO建立的会话。

用户平台是Windows 7。

关键是要保护用户在需要执行此操作(每天)时,不会对每个文件(下载,保存位置等)进行大量点击。

此时所有文件都是PDF,但将来可能会发生变化。

首选浏览器无关的解决方案(我认为未来的浏览器更新会更加强大。)

但如果需要,我们可以将它建立在特定的浏览器上。

你会如何从Javascript中做到这一点?

2 个答案:

答案 0 :(得分:0)

正如我的问题的评论所说,出于安全原因,浏览器并不真正允许这样做。

我现在的解决方法(仅使用IE11测试)是手动更改用户浏览器的安全设置,然后使用AJAX将文件作为blob下载到javascript变量中,然后将相同的blob上传到我自己的服务器再次使用AJAX。

“我自己的服务器”是为此目的而创建的Django站点,它也知道当天要下载哪些文件,并提供所需的javascript。在单独的浏览器选项卡中执行SSO后,用户访问此站点以启动每日下载。

在服务器上,我可以执行所述文件所需的任何操作。

非常感谢这篇文章https://stackoverflow.com/a/13887220/833320,以便在AJAX中处理二进制数据。

1)在IE中,将涉及的站点添加到“本地Intranet区域”,并为此区域启用“跨域访问数据源”以克服CORS保护,否则会阻止此操作。

当然,请考虑此中涉及的安全后果......

2)在javascript(浏览器)中,将文件下载为blob并将结果数据发布到我自己的服务器:

var x = new XMLHttpRequest();
x.onload = function() {
    // Create a form
    var fd = new FormData();
    fd.append('csrfmiddlewaretoken', '{{ csrf_token }}'); // Needed by Django
    fd.append('file', x.response); // x.response is a Blob object

    // Upload to your server
    var y = new XMLHttpRequest();
    y.onload = function() {
        alert('File uploaded!');
    };
    y.open('POST', '/django/upload/');
    y.send(fd);
};
x.open('GET', 'https://external.url', true);
x.responseType = 'blob';    // <-- This is necessary!
x.send();

3)最后(在'/ django / upload /'的Django视图中),接收上传的数据并保存为文件 - 或者其他......

filedata = request.FILES['file'].read()

with open('filename', 'wb') as f:
    f.write(filedata)

谢谢大家,感谢您的评论。

是的,真正的解决方案是克服SSO(需要用户),所以这一切都可以由服务器本身完成。

但至少我学到了一些关于使用现代XMLHttpRequests获取/发布二进制数据的知识。 :)

答案 1 :(得分:0)

实际上,我遇到类似的问题,我想下载一个二进制文件(图像)并存储它,然后在需要时使用它,所以我决定通过Fetch API Get调用下载它:

const imageAddress = 'an-address-to-my-image.jpg'; // sample address

fetch(imageAddress)
  .then(res => res.blob)  // <-- This is necessary!
  .then(blobFileToBase64)
  .then(base64FinalAnswer => console.log(base64FinalAnswer))

blobFileToBase64是一个辅助函数,可将blob二进制文件转换为base64数据字符串:

const blobToBase64 = blob => {
  const reader = new FileReader();
  reader.readAsDataURL(blob);
  return new Promise(resolve => {
    reader.onloadend = () => {
      resolve(reader.result);
    };
  });
};

最后,我有了base64FinalAnswer,我可以用它做任何事情。