最近、私は大容量のファイルに大きな需要をアップロードする必要性を満たし、研究、テンセント7頭の牛はそう、このフロントエンド仕上げ大容量のファイルに関連する機能をアップロードし、スライスセグメントのアップロード機能を曇らせます。
一部の企業では、大容量ファイルのアップロードこのような大規模なストレージExcelのスプレッドシートのデータをアップロードするなど、より重要な対話シナリオは、オーディオおよびビデオファイルをアップロードしています。(より多くのパケットが送信される、再送パケット損失確率が大きくなる)、ファイルサイズが比較的大きい、またはネットワークの状態が悪い、アップロード時間が長くなります場合は、ユーザーがページを更新することはできません、あなただけのリクエストが完了するまで待機することができます。
以下のファイルのアップロードから始めて、自分の考えを整理し、大きなファイルをアップロードし、関連するコードの例を示し、組み込みのPHPによると、ファイル分割及びスプライシング方法は非常に簡単ですので、サービス側のコード例は、PHPを使って書かれました。
この記事のサンプルコードは、githubの上で主要なリファレンスです
大容量ファイルのアップロード話
大容量ファイルのアップロードを切断
いくつかの方法でファイルのアップロード
まず、ファイルをアップロードするにはいくつかの方法を見てください。
アップロードに共通フォーム
従来の形態のアップロードが良い選択であることを示すためにPHPを使用してください。最初のビルドファイルのアップロードフォーム、フォームを送信してにenctype =「multipart / form-データ」であるコンテンツの種類を指定し、フォームがバイナリデータをアップロードする必要がありますことを示しています。
書き込みindex.phpのアップロードファイルはコードを受信すると、あなたは、move_uploaded_file方法(PHP大法が良いですが...)を使用することができます
フォームフォームは、大きなファイルをアップロードするとき、問題のサーバーのタイムアウトを満たすことは容易です。XHRすることにより、フロントエンドは、2つのアイデアにより、通常は、非同期的にファイルをアップロードすることができます。
アップロードファイルのエンコーディング
ファイルをエンコードすることで、その後、サーバ側でデコードし、その主な原則を達成するために、フロントエンドでブログをアップロードする前に画像圧縮を達成書いた最初のアイデアは、渡されたBASE64に画像を変換することです
varimgURL = URL.createObjectURL(ファイル);
ctx.drawImage(imgURL、0、0);
//像の符号化を取得し、その後、非常に長い文字列として渡された絵は、
VARDATA = canvas.toDataURL( "画像/ JPEG"、0.5)。
サーバーでは、比較的単純な、第1の復号base64である行われる必要があるし、その後に画像の保存
$ imgData = $ _REQUEST [ 'imgData'];
$ BASE64 =爆発( ''、$ imgData)[1]。
$ IMG = BASE64_DECODE($ BASE64)。
$ URL = './test.jpg';
もし(ますfile_put_contents($ urlには、$ IMG)){
出口(json_encode(配列(
URL => $ URL
)));
}
BASE64は、大容量のために、より大きな体積原画像より(3つのバイトを4バイト、したがって、エンコードされたテキストに変換されるBASE64としては、元の言語の約3分の大きな割合を提示する)という欠点をコードファイル、アップロードと解析時間が大幅に増加します。
base64での詳細な知識は、Base64でノートを参照してください。
base64エンコーディングに加えて、ファイルの内容もバイナリ形式でアップロードされたフロントエンドで直接読み取ることができます
//バイナリファイルを読みます
functionreadBinary(テキスト){
VARDATA = newArrayBuffer(text.length)。
varui8a = newUint8Array(時間0)。
{(I ++; I <text.length VARI = 0)のための
ui8a [I] =(text.charCodeAt(I)&0xffの)。
}
console.log(ui8a)
}
varreader = newFileReader。
読者。=関数{
readBinary(this.result)//直接の結果やアップロードを読みます
}
ファイルの//内容は、入力からフィールドFileReaderの中に入れた結果を読んで
(ファイル)reader.readAsBinaryString。
FORMDATA非同期アップロード
いるFormDataは、主に、より柔軟にAjaxリクエストすることができる送信要求/値ペアのキーのセットをアセンブルするために使用されます。あなたは、フォーム送信いるFormDataを使用してシミュレートすることができます。
letfiles = e.target.files // GET入力ファイルオブジェクト
letformData = newFormData。
formData.append( 'ファイル'、ファイル);
axios.post(URL、FORMDATA)。
リクエストを処理サーバは、直接、実質的に同じ形を形成します。
ページを更新せずにIFRAME
フォームのフォームターゲット属性が発生したため(例えばIEなど)、ブラウザの低いバージョンでは、XHR直接アップロードFORMDATAをサポートしていないので、フォームがファイルのみをアップロードするために使用することができ、それ自体を形成するには、ジャンプページに提出されますその値はあり
_self、デフォルト値は、ページが同じウィンドウに応じて開かれます
_blank、新しいウィンドウで開きます
_parent、親ウィンドウで開きます
_top、最上位のウィンドウで開きます
framename、指定のiframeの名前にオープン
あなたは、ユーザーが非同期アップロードファイルの感覚を体験できるようにする必要がある場合は、framename指定のiframeによって達成することができます。targetプロパティの形式は、返されたデータが戻り結果と同様に、これだけのiframeが更新されます、これはiframeを受け入れられますが、また、インラインフレーム内のテキストを解析することによって得ることができ、その後、目に見えないのiframeに設定されています。
functionupload {
varnow = + NEWDATE
varid = '枠' +今
$( "本体")追加します。( `<IFRAMEスタイル= "表示:なし;" NAME = "$ {ID}" ID = "$ {ID}"/>`)。
変数$フォーム= $( "#myForm")
$ form.attr({
「アクション」:「/index.php」
「メソッド」:「ポスト」、
「ENCTYPE」:「マルチパート/フォームのデータ」、
「コードする」:「マルチパート/フォームデータ」、
"ターゲット":ID
})。参加する
$( "#" + ID).on( "負荷"、関数{
varcontent = $(この).contents.find( "身体")。テキスト
{試します
VARDATA = JSON.parse(コンテンツ)
}キャッチ(E){
console.log(E)
}
})
}
大容量ファイルのアップロード
今、いくつかの方法で大容量ファイルのアップロードを達成するためにルックアウトの問題は、上述したように、満たさアップロードされます
大きなファイルをアップロードするときに、フォームのアップロードとiframeのアップロードせずにページを更新するには、アップロードファイルは実際にフォームタグ、要求全体がブラウザに完全に処理されます。この方法で行われている、あなたは状況がタイムアウトを要求が発生する可能性があり
fromDataすることで、パッケージは実際のパラメータXHR要求のセットで、アナログ形式の要求は、大容量ファイルのアップロードタイムアウトの問題を回避することはできません
コーディングアップロードし、我々は、コンテンツのアップロードをより柔軟に制御することができ
大容量ファイルのアップロード主な問題の嘘:同じ要求では、大量のデータをアップロードするために、プロセス全体で結果が比較的長くなり、失敗したアップロードした後、最初からやり直す必要があります。ただ、考えて、我々は複数の要求に要求を分割する場合、各要求は、時間を短縮し、要求が失敗した場合、あなただけの再送信この要求は、あなたが大きなファイルを解くことができるそうならば、ゼロからスタートすることなく、必要なする必要がありますアップロードの問題?
統合された上記の問題は、それは以下のいくつかの需要を達成するために、その大きなファイルをアップロードする必要が表示されます
サポート分割アップロード要求(すなわちスライス)
HTTPのサポート
サポート一時停止およびshowアップロードの進捗状況のアップロード
のは、これらの機能を有効にしてみましょう、最も重要な機能をアップスライスするあるように思われます。
スライスファイル
参考:大容量ファイルのアップロードを切断
最初の長い私たちは、ファイルのバイナリコンテンツを取得し、その内容を分割し、そして最終的には各スライスにサーバにアップロードとしてフロントエンドで、アップロードをコードします。
Javaでは、オブジェクトは、Blobオブジェクトは、スライスへの重要な方法が含まれている,,私たちはこの方法によるスプリットバイナリファイルすることができ、ファイルのファイルBlobオブジェクトのサブクラスです。
ここでは、開発者のためのUP6の制御を達成するのを助けるために、分割の詳細を気にしないために、唯一のビジネスロジックを気にする必要があり、開発者がすることができ、分割されたファイルの一例です。
コントロールアップロード時間は、サーバーがデータを受信した後、開発者が自分で処理することができ、各ブロックのデータファイルの関連情報を追加します。
サーバはスライスを受信した場合、その後、彼らは一緒にスプライスすることができ、次のサンプルコードは、スライススプライシングPHPで
UP6のために、開発者は、UP6のサンプルコードが提供されている、このロジックが実装されているスプライスされる必要はありません。
保証一意性は、コントロールはMD5、MD5ファイルをブロックする、などの各ファイルブロックのブロックインデックスとして、情報を追加します
HTTP
UP6は、レジューム機能、サーバ情報ファイル内UP6は、ファイルの進捗情報の保存も、クライアントに保存されていています。ファイルアップロードコントロールが自動的にスケジュール情報をロードするときに、開発者は、これらの詳細を気にする必要はありません。論理ファイルブロックの処理にのみインデックスファイルブロックに従って同定することができます。
このとき、ページを更新またはアップロードするには、ブラウザを閉じて、再び同じファイルをアップロードし、以前に成功したアップロードのスライスは、再アップロードされません。
HTTPサーバ側のロジックはレコードだけのスライスをアップロードすることができます得るために、内部getUploadSliceRecord問合せインタフェースのサービス側を呼び出して、実質的に同様の達成するために、したがって、ここでは展開されません。
あなたがmkfileによってインターフェースを呼び出す場合は、ディスクの内容を除去することができるスライス、およびクライアントは、これらのセクションは明らかにディスクに保存されているせ、mkfileによってインタフェースを起動していない場合:加算HTTPでもスライスが期限切れ状況を考慮する必要があります信頼できないが、通常の状況下では、スライスされたアップロードの有効期間は、期間にわたって、削除されますました。これらの理由により、HTTPはまた、有効期限が切れ同期ロジックスライスを実装する必要があります。
再開効果
アップロードの進行状況と一時停止
各スライスは、メソッドのxhr.uploadの進歩により、アップロードの進行状況を監視するために実装することができます。
実装は比較的単純で、サスペンドアップロードし、あなただけのHTTPアップロードのように最初のセクションのリストを取得する同様の回復がアップロードされ、その後、いない再送信されてきたが、猶予効果をアップロードするために、xhr.abortによってアップロードされ、現在未解決アップロードされたスライスをキャンセルすることができますスライスをアップロードします。
それが達成されないスペースの関係、ここではアップロードの進捗状況や一時停止機能に起因します。
結果を実現:
概要
現在、一部のコミュニティが既にテンセントクラウドなど、など7牛SDK、SDKなどの大容量ファイルのアップロードソリューションを、成熟があり、我々は、おそらく大規模なライブラリをアップロード手動で単純なファイルを実装する必要はありませんが、原理はまだ非常に必要であることを理解します。
実装するために大容量ファイルのアップロードだけでなく、いくつかの大きなファイルのアップロード機能のニーズを第一に、我々はいくつかの方法にフロントファイルアップロードを終えており、その後、いくつかのシナリオを説明します
スライス法によるBlobオブジェクトは、セクションにファイルを分割します
条件およびパラメータを復元するために必要なファイルサーバを仕上げ、実証されたスライスのPHPファイルに縮小
HTTPは、スライスをアップロードし、レコードを格納することによって達成され、
マージメモリ不足を回避するためのファイル、スライスされた有効期限ポリシー、アップロードの進捗状況や一時停止、深い行くか叶う、それを学ぶために継続していなかった。またのような質問の数を左に
バックエンドのコード・ロジックの大部分は、現在のMySQLやOracle、SQLをサポートし、同じです。データベースを構成する必要性を使用する前に、この記事を書くために私を指すことができます。http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87 %E4%BB%B6%E6
%96%AD%E7%82%B9%E7%BB%AD%E4%以下のBC%A0%E4%B8%8A%E4%BC%のA0 / 議論するグループへの歓迎:374992201