2016-09-25 22 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 
}