简体   繁体   English

javascript-在本地生成和下载大文件

[英]javascript - locally generating and downloading a huge file

I have the following JavaScript code which downloads a file, which I can't help but think I got from here: Create a file in memory for user to download, not through server 我有以下JavaScript代码可以下载文件,但我不禁觉得自己是从这里下载的: 在内存中创建文件供用户下载,而不是通过服务器下载

However, this function crashes in Chrome because I'm trying to download too much data (it might be a couple of MB, but it seems to work OK for downloads under 1 MB. I haven't done many metrics on it). 但是,此功能在Chrome中崩溃是因为我尝试下载过多的数据(可能是几MB,但是对于1 MB以下的下载似乎可以正常工作。我没有对其进行很多度量)。

I really like this function because it lets me create a string from an existing huge JavaScript variable and immediately download it. 我真的很喜欢这个函数,因为它可以让我从一个现有的巨大JavaScript变量中创建一个字符串,然后立即下载它。

So my two questions then are: 所以我的两个问题是:

A) Whats causing the crash? A)是什么原因导致飞机坠毁? Is it the size of the string text or is there something in this function? 它是字符串text的大小还是此函数中有内容? I read that 60MB strings were possible in JavaScript and I don't think I'm quite reaching that. 我读到在JavaScript中可以使用60MB的字符串,但我认为我还没有达到这个目标。

B) If it is this function, is there another simple way to download some huge-ish file that allows me to generate the content locally via JavaScript? B)如果是此功能,是否有另一种简单的方法可以下载一些庞大的文件,使我可以通过JavaScript在本地生成内容?

function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);
  element.click();
  document.body.removeChild(element);
}

Does it work in other browsers? 是否可以在其他浏览器中使用? Try using the debugger and set a break point just inside the function and step through. 尝试使用调试器,并在函数内部设置一个断点并逐步执行。

Try breaking up the element.setAttribute and the data content by creating a var that holds the string you are going to set to href, that way you can see more failure points. 尝试通过创建一个包含要设置为href的字符串的var来分解element.setAttribute和数据内容,这样您可以看到更多的失败点。

See if the encodeURIComponent function is failing with large strings. 查看encodeURIComponent函数是否使用大字符串失败。

Strings are immutable in javascript, for those who are privy it means that their creation is final, you can't modify the string, or append to one, you have to create a new one for every change. 字符串在javascript中是不可变的,对于有特权的人来说,这意味着它们的创建是最终的,您无法修改字符串或将其追加到字符串中,您必须为每次更改创建一个新的字符串。 encodeURIComponent which url encodes a string is possibly making thousands of changes escaping a > 1mb string depending on the contents of the string. url对字符串进行编码的encodeURIComponent可能会进行成千上万的更改,从而根据字符串的内容转义大于1mb的字符串。 And even if you are using zero characters that need escaped, when you call that function and then append it to the 'data:text/plain;charset=utf-8,' string, it will create a new string from those two, effective doubling the memory needed for that action. 即使您使用了需要转义的零个字符,当您调用该函数并将其附加到'data:text/plain;charset=utf-8,'字符串后,它也会根据这两个字符串创建一个新的字符串,有效使该操作所需的内存增加一倍。

Depending on how the particular browser is handing this function, its not optimized for long strings at all, since most browsers have a url character limitation of ~2000 characters ( 2048 typically ) then it's likely that the implementation in the browser is not doing a low level escape. 取决于特定浏览器如何使用此功能,它根本没有针对长字符串进行优化,因为大多数浏览器的url字符限制为〜2000个字符(通常为2048个),因此浏览器中的实现可能执行得不尽人意。级别逃生。 If this function is indeed the culprit, you will have to find another way to uri escape your string. 如果此函数确实是罪魁祸首,则您将不得不寻找另一种方法来uri转义您的字符串。 possibly a library or custom low level escape. 可能是库或自定义的低级别转义。

If the debugger shows that this function is not the issue, the obvious other bottleneck would be when you append this enormous link to the dom, the browser could be freezing there attempting to process this command, and for that it may require a completely different solution to your downloading issue. 如果调试器显示此功能不是问题,那么明显的其他瓶颈将是当您将此巨大链接附加到dom时,浏览器可能会冻结在那里尝试处理此命令,因此可能需要一个完全不同的解决方案您的下载问题。

Though this is just speculation, hopefully it leads you in the right direction. 尽管这只是猜测,但希望它能引导您朝正确的方向发展。

While I marked Rickey's answer as the correct one because it got me to the right answer, a workaround I found for this was here: 当我将Rickey的答案标记为正确的答案时,因为它使我获得了正确的答案,但我发现了以下解决方法:

JavaScript blob filename without link 没有链接的JavaScript Blob文件名

The accepted answer at this link was capable of handling more than 8MB, while the data URI was capable of handling 2MB, because of Chrome's limit on URI length. 由于Chrome对URI长度的限制,此链接上可接受的答案能够处理8MB以上的数据,而数据URI能够处理2MB的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM