2016-09-25 23 views
5

我想从我的服务器下载加密文件,解密并将其保存到本地。我想解密文件并在下载时将其写入本地,而不是等待下载完成,解密并将解密后的文件放入锚标签中。我想这样做的主要原因是,对于大文件,浏览器不必在内存中存储数百兆字节或几千兆字节。JavaScript:写入下载流

+0

您是否有解密算法的数据? – guest271314

+0

我打算使用AES。 – Hephaestious

+0

您无法使用浏览器Javascript写入用户计算机上的文件。所以你不能做你想要达到的目标,除非你正在与Electron或类似的工作。 –

回答

3

这只会有可能与服务工作者+的组合取+流 几个浏览器有工人和获取,但即使较少的支持与流获取(闪烁)

new Response(new ReadableStream({...}))

我有内置流媒体文件保护LIB与其他服务工作者进行沟通拦截网络请求:StreamSaver.js

从这儿节点的流不同的一点就是一例

function unencrypt(){ 
    // should return Uint8Array 
    return new Uint8Array() 
} 

// We use fetch instead of xhr that has streaming support 
fetch(url).then(res => { 
    // create a writable stream + intercept a network response 
    const fileStream = streamSaver.createWriteStream('filename.txt') 
    const writer = fileStream.getWriter() 

    // stream the response 
    const reader = res.body.getReader() 
    const pump =() => reader.read() 
     .then(({ value, done }) => { 
      let chunk = unencrypt(value) 

      // Write one chunk, then get the next one 
      writer.write(chunk) // returns a promise 

      // While the write stream can handle the watermark, 
      // read more data 
      return writer.ready.then(pump) 
     ) 

    // Start the reader 
    pump().then(() => 
     console.log('Closed the stream, Done writing') 
    ) 
}) 

还有另外两种方式可以用xhr获得流式响应,但它不是标准的,如果你使用它们,它就不会成为mather(responseType = ms-stream || MOZ-分块-arrayBuffer)因为StreamSaver取决于取+ ReadableStream任何方式,不能以任何其他方式使用

以后你就可以做这样的事情的时候WritableStream +变换流得到实施以及

fetch(url).then(res => { 
    const fileStream = streamSaver.createWriteStream('filename.txt') 

    res.body 
     .pipeThrogh(unencrypt) 
     .pipeTo(fileStream) 
     .then(done) 
}) 

还值得一提的是,默认的下载管理器通常与后台下载相关联,所以当他们看到下载时,ppl有时会关闭选项卡。但这一切都发生在主线程中,因此您需要在用户离开时警告用户

window.onbeforeunload = function(e) { 
    if(download_is_done()) return 

    var dialogText = 'Download is not finish, leaving the page will abort the download' 
    e.returnValue = dialogText 
    return dialogText 
}