2016-08-05 14 views
3

Google Chromeでダウンロードの問題が発生しました。 私はRuby 2.2、Rails 4.2、AngularJS 1.2を使用しています。Google Chromeで大きなファイル(最大15 MB)をダウンロードする際の問題

ここにデータベースはありません。私たちはAPIを使いこなしています。ダウンロードしようとしているファイルは約7 MBです。それは私たちに "失敗:ネットワークエラー"を与えます。 Firefoxではうまく動作しますが。

APIからJSONでバイナリデータを取得しています。私たちはそれを解析しています。そして:私たちはAngularJSを使用していると

send_data response_fields["attachment"], type: response_fields["mimeType"], disposition: 'attachment', filename: params[:filename] 

、我々はAngularJSコントローラでその値をキャッチされ、その後、としてそれを変換する:これは、小さいファイルサイズのためのFirefox &でもChromeで動作します

var str = data; 
var uri = "data:" + mimeType + ";base64," + str; 

var downloadLink = document.createElement("a"); 
downloadLink.href = uri; 
downloadLink.download = filename; 
document.body.appendChild(downloadLink); 
downloadLink.click(); 
document.body.removeChild(downloadLink); 

。なぜChrome上でサイズが大きくなるとエラーが発生するのか不明です。

提案がありますか?

ありがとうございました。

+2

は、私は同じことを取得していますブロブの代わりにBASE64 – Endless

+0

を使用してみてくださいエラー:ダウンロードに失敗しました - ネットワークエラー – Avinash

答えて

6

これは、これらの質問12とほぼ同じですが、キャンバス要素を特に扱うため、ここではよりグローバルな解決策を書き直していきます。

この問題は、サイズ制限クロムがアンカー(<a>download属性に設定されていることが原因です。なぜ彼らがそれをしたのかはわかりませんが、解決は簡単です。

dataURIをBlobに変換し、このBlobからObjectURLを作成し、このObjectURLをアンカーのダウンロード属性として渡します。

// edited from https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#Polyfill 
 
function dataURIToBlob(dataURI, callback) { 
 

 
    var binStr = atob(dataURI.split(',')[1]), 
 
    len = binStr.length, 
 
    arr = new Uint8Array(len), 
 
    mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] 
 

 
    for (var i = 0; i < len; i++) { 
 
    arr[i] = binStr.charCodeAt(i); 
 
    } 
 

 
    return new Blob([arr], { 
 
    type: mimeString 
 
    }); 
 

 
} 
 

 
var dataURI_DL = function() { 
 

 
    var dataURI = this.result; 
 
    var blob = dataURIToBlob(dataURI); 
 
    var url = URL.createObjectURL(blob); 
 
    var blobAnchor = document.getElementById('blob'); 
 
    var dataURIAnchor = document.getElementById('dataURI'); 
 
    blobAnchor.download = dataURIAnchor.download = 'yourFile.mp4'; 
 
    blobAnchor.href = url; 
 
    dataURIAnchor.href = dataURI; 
 
    stat_.textContent = ''; 
 

 
    blobAnchor.onclick = function() { 
 
    requestAnimationFrame(function() { 
 
     URL.revokeObjectURL(url); 
 
    }) 
 
    }; 
 
}; 
 

 
// That may seem stupid, but for the sake of the example, we'll first convert a blob to a dataURI... 
 
var start = function() { 
 

 
    stat_.textContent = 'Please wait while loading...'; 
 
    var xhr = new XMLHttpRequest(); 
 
    xhr.responseType = 'blob'; 
 
    xhr.onload = function() { 
 
    status.textContent = 'converting'; 
 
    var fr = new FileReader(); 
 
    fr.onload = dataURI_DL; 
 
    fr.readAsDataURL(this.response); 
 
    }; 
 
    xhr.open('GET', 'https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4?dl=0'); 
 
    xhr.send(); 
 

 
    confirm_btn.parentNode.removeChild(confirm_btn); 
 
}; 
 

 
confirm_btn.onclick = start;
<button id="confirm_btn">Start the loading of this 45Mb video</button> 
 
<span id="stat_"></span> 
 
<br> 
 
<a id="blob">blob</a> 
 
<a id="dataURI">dataURI</a>

とFF用jsfiddle version、彼らはスタック・スニペットからdownload属性を許可していないので...

+0

クロムで制限されたURIが2 MBに制限されているのは悲しいです。http://stackoverflow.com/a/41755526/704008大きなサイズのBLOBを使用するための大きな回避策。 –

+0

FFとクロムフィドルの違いは何ですか?同じように見える –

+0

@PranavSingh、ねえ、彼らは同じです(IIRC)。それはちょうどFFが 'download'属性とstacksnippetsで奇妙なことをしただけです(私の場合は、ダウンロードポップアップを表示せず、拡張子なしでBLOBの名前で保存しました)しかし、実際FFで固定されているようです52 – Kaiido

関連する問題