像mega.co.nz这样下载文件的方法

96

今天我查看了mega.co.nz并且对其中一些功能感到兴奋。例如在下载页面中,它会通过浏览器下载文件,然后使用JavaScript解密。

例如,查看此链接以下载PNG文件:

https://mega.co.nz/#!7JRgFJzJ!efpJGWuPhYczLexY19ex82nuwfs4sR_DG4JXddeClH4

在此链接中,它将在浏览器内开始下载。我检查了在“检查元素”选项卡下的网络标签,它会使用AJAX下载文件的部分,之后完成文件所有部分的下载,会自动将它们全部保存在计算机上的一个文件中!

我想知道他们是如何做到的?你能否解释或者提供一些关于在浏览器内下载文件的资源链接?

还可以只使用JavaScript完成吗?还是需要使用一些flash插件或其他类似的东西?


3
如果你下载一个大文件,系统会因为不断地翻页而变得非常缓慢。 - kinokijuf
4个回答

107
Mega使用多种不同的方法来达到此目的(截至2013年11月27日):
  1. 文件系统 API(Chrome/Firefox 扩展 polyfill)
  2. Adobe Flash SWF 文件编写器(旧浏览器后备)
  3. BlobBuilder(IE10/IE11)
  4. MEGA Firefox 扩展(已弃用)
  5. Arraybuffer/Blob(内存中)+ a[download](用于支持 a[download] 的浏览器)
  6. MediaSource(实验性流媒体解决方案)
  7. Blob 存储在 IndexedDB 存储中 + a[download](Firefox 20+,优于内存中的 Blob 方法)
(来源:https://eu.static.mega.co.nz/js/download_6.js

1
是的,您提供的示例(http://jsfiddle.net/kGLnP/5/)应该适用于Firefox,但仅适用于最新版本(20或更高版本,请参见https://developer.mozilla.org/en-US/docs/HTML/Element/a了解更多支持信息)。我刚刚阅读了Mega的JavaScript代码并更新了我的答案。(它将回答您关于其他浏览器的问题。基本上,当它们无法使用仅JS解决方案时,它们将诉诸于使用Flash。) - roberto
罗伯托的回答还是最新的吗?我已经尝试在Firefox中从mega.co.nz下载大文件并禁用了Flash,但仍然可以下载。当尝试下载“大文件”时,Firefox要求批准存储超过50MB,这使我认为他们使用了indexedDB。 - shacharz
1
不,它(真的)不是最新的,当前的下载脚本在这里:https://eu.static.mega.co.nz/download_46.js。我快速浏览了一下,它仍然是大致相同的技巧,加入了一些新的内容,包括通过缓存(使用IndexedDB,正如你所猜测的那样)来提高性能。当我有时间阅读代码时,我会更新我的答案。 - roberto
你知道有没有任何JS/Jquery插件可以使用javascript实现跨浏览器下载? - Niros
@Jimbo:基本上是的。最新版本似乎是这个:https://eu.static.mega.co.nz/js/download_23.js - roberto
显示剩余4条评论

5
这里提供了使用Blob和URL API实现浏览器内分块下载的基本方法,可以在这里找到代码。它可以同时进行4个请求来下载文件并显示下载进度。请注意,设置range报头似乎一般不是XHR请求的好主意,可以看看这个话题
下载时: 下载时 下载完成后: 下载完成后 另一个有趣的话题是从Mega实现暂停/恢复功能。当前浏览器的XHR API不提供该功能,因此您唯一的机会就是进行多个小块大小的下载,并放弃已下载部分的小块,这也似乎是Mega所采用的方式。但是,fetch流功能可用于此目的,我还没有深入探索,但可以在这里找到相关文档。
另外,可以看看这些很棒的项目:

1

MEGAcmd

这里有官方命令行界面megacmd。你也可以在https://github.com/meganz/MEGAcmd上构建它的源代码。

megacmd是Mega SDK的包装器,如果你决定自己编译它,你需要与Mega SDK相同的依赖项(在Ubuntu上)如下所列。

有关使用详细信息,请参阅MEGAcmd用户指南

Mega SDK

Mega SDK可以通过遵循github页面上的步骤进行编译。它包括megacli实用程序,它是一个交互式shell,用于同步和下载/上传。

## compilation steps for ubuntu
git clone --depth 1 https://github.com/meganz/sdk megasdk
cd megasdk
sudo apt install libcurl4-openssl-dev  libc-ares-dev libssl-dev libcrypto++-dev  zlib1g-dev libsqlite3-dev  libfreeimage-dev libswscale-dev
autogen.sh
./configure
make -j 8  ## pass the number of CPUs you have to speed up compilation
sudo make install

mega.py Python模块(已弃用)

对于那些在搜索实际下载链接的过程中发现这个问题的人,这里有一个简单的Python脚本,它使用mega.py模块(使用sudo pip install mega.py进行安装):

import sys
import getpass
#install the module with: 'sudo pip install mega.py'
from mega import Mega

email = '_your_megamail_@domain.com'
password = getpass.getpass(prompt='Mega password for {}:'.format(email))

mega = Mega({'verbose': True})
m = mega.login(email, password)
m.download_url(sys.argv[1])

这个脚本适用于Python 2.7,需要输入mega.nz链接的URL。

getpass 用于在控制台中安全地输入密码,以避免在脚本中存储密码 - 如果您愿意硬编码密码,则可以在第7行设置密码。

megatools

在大多数Linux/posix系统中,您可以从标准存储库(即megatools)安装megatools。

在Ubuntu/Debian上:

apt install megatools

在MacOS上:
brew install megatools

安装后,您将找到许多命令行实用程序,其中包括 megadl,它可以下载共享文件和您自己的文件。有关详细信息,请参见 megadl -h

Download files LIKE mega with tag javascript - Trương Quốc Khánh

0

截至2020年,您可以使用服务工作者(Service Workers)无缝地将自定义代码与浏览器内置的下载管理器集成:https://developers.google.com/web/updates/2016/06/sw-readablestreams

我猜您需要以下标头才能下载文件而不是查看:

 headers: {
   'Content-Type': 'application/octet-stream',
   'Content-Disposition': 'attachment; filename="your_filename.bin"',
 }

就我个人而言,我发现这种方法在Google Chrome和Firefox中都能完美运行,并且我已经在生产环境中使用它了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接