HTML5 + jQueryで複数ファイルのアップロード時、プログレスバーを表示
HTML5 + jQueryで複数ファイルのアップロードを試してみました。CodeIgniter 3 + HTML5 FileAPI + jQueryで複数ファイルのアップロード
アップロードの進捗を表示するプログレスバーを表示してみます。
progress
HTML5で、プログレスバーを表示するタグが追加されました。
これを使用して進捗表示してみます。
今回もCodeIgniter 3と組み合わせて使用してみます。
・application/views/fileupload.php
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>ファイルアップロード</title>
- <script src="//code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
- <script>
- <!--
- $(function(){
- // ファイルのアップロード処理
- var uploadFiles = function(files) {
- // FormDataオブジェクトを用意
- var fd = new FormData();
- // ファイルの個数を取得
- var filesLength = files.length;
- // ファイル情報を追加
- for (var i = 0; i < filesLength; i++) {
- console.log(files[i]["name"]);
- fd.append("files[]", files[i]);
- }
- // Ajaxでアップロード処理をするファイルへ内容渡す
- $.ajax({
- url: 'fileupload/upload',
- type: 'POST',
- data: fd,
- processData: false,
- contentType: false,
- xhr : function(){
- var XHR = $.ajaxSettings.xhr();
- XHR.upload.addEventListener('progress',function(e){
- var progre = parseInt(e.loaded/e.total * 100);
- $('#prog').val(progre);
- $('#pv').html(progre);
- });
- return XHR;
- }
- }).done(function(data) {
- console.log(data);
- }).fail(function(data) {
- console.log(data.responseText);
- });
- };
- // ファイルドロップ時の処理
- $('#drag-area').on('drop', function(e){
- // デフォルトの挙動を停止
- e.preventDefault();
- // ファイル情報を取得
- var files = e.originalEvent.dataTransfer.files;
- uploadFiles(files);
- // デフォルトの挙動を停止 これがないと、ブラウザーによりファイルが開かれる
- }).on('dragenter', function(){
- return false;
- }).on('dragover', function(){
- return false;
- });
- // ボタンを押した時の処理
- $('#btn').on('click', function() {
- // ダミーボタンとinput[type="file"]を連動
- $('#file_selecter').click();
- });
- $('#file_selecter').on('change', function(){
- // ファイル情報を取得
- var files = this.files;
- uploadFiles(files);
- });
- });
- -->
- </script>
- </head>
- <body>
- <div id="drag-area" style="border-style: dashed;background-color: #042943; color: #ffffff;">
- <p>アップロードするファイルをドロップ</p>
- <p>または</p>
- <div class="btn-group">
- <input id="file_selecter" type="file" multiple="multiple" style="display:none;" name="files"/>
- <button id="btn">ファイルを選択</button>
- </div>
- </div>
- <progress value="0" id="prog" max=100></progress>(<span id="pv" style="color:#00b200">0</span>%)
- </body>
- </html>
コントローラー側は前回と同様です。
・application/controllers/Fileupload.php
- <?php
- class Fileupload extends CI_Controller {
- // アップロード用の画面を表示
- public function index() {
- $this->load->view('fileupload');
- }
- // 画像アップロード
- public function upload() {
- $count = count($_FILES['files']['tmp_name']);
- for ($i = 0 ; $i < $count ; $i ++ ) {
- $tmp_name = $_FILES["files"]["tmp_name"][$i];
- if (!is_uploaded_file($tmp_name)) {
- continue;
- }
- move_uploaded_file($tmp_name, FCPATH.$_FILES["files"]["name"][$i]);
- }
- // 保存結果を返信
- $this->output
- ->set_content_type('application/json')
- ->set_output(json_encode(['result' => $count]));
- }
- }
初期表示
ファイルを選択すると、プログレスバーに進捗が表示されました。
PHP Warning: Maximum number of allowable file uploads
複数ファイルをまとめて1回でPOSTするため、
選択したファイルの総容量が大きくなるとサーバー側のPOST値の上限を
あっさり超えてしまいます。
また、phpのデフォルトでは1回のPOSTでアップロードできるファイル数は20個までです。
これらの制約を加味して、プログラムを修正してみました。
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>ファイルアップロード</title>
- <script src="//code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
- <script>
- <!--
- $(function(){
- // フォームデータのアップロード処理
- var uploadFormData = function(fd, totalBytes, tasks, index) {
- var xhr_func = function(){
- var XHR = $.ajaxSettings.xhr();
- XHR.upload.addEventListener('progress',function(e){
- tasks[index] = e.loaded;
- var upload = 0;
- tasks.forEach(function(bytes) {
- upload += bytes;
- });
- var progre = parseInt(upload/totalBytes * 100);
- $('#prog').val(progre);
- $('#pv').html(progre);
- });
- return XHR;
- };
- // Ajaxでアップロード処理をするファイルへ内容渡す
- $.ajax({
- url: 'fileupload/upload',
- type: 'POST',
- data: fd,
- processData: false,
- contentType: false,
- xhr : xhr_func
- }).done(function(data) {
- console.log(data);
- }).fail(function(data) {
- console.log(data.responseText);
- });
- };
- // ファイルのアップロード処理
- var uploadFiles = function(files) {
- // ファイルの個数を取得
- var filesLength = files.length;
- // 選択されたファイルの総容量を取得
- var totalBytes = 0;
- for (var i = 0; i < filesLength; i++) {
- totalBytes += files[i].size;
- }
- console.log(totalBytes);
- var fd = new FormData();
- var fdBytes = 0;
- var fdCount = 0;
- var tasks = [];
- for (var i = 0; i < filesLength; i++) {
- // 指定バイト数を超えないかチェック
- var currentBytes = files[i].size;
- if (((fdBytes + currentBytes) >= 8000000) || (fdCount >= 20)) {
- // 超えたらアップロード実行
- tasks.push(0);
- uploadFormData(fd, totalBytes, tasks, tasks.length - 1);
- fd = new FormData();
- fdBytes = 0;
- fdCount = 0;
- }
- fdBytes += currentBytes;
- fdCount += 1;
- fd.append("files[]", files[i]);
- }
- if (fdCount > 0) {
- tasks.push(0);
- uploadFormData(fd, totalBytes, tasks, tasks.length - 1);
- }
- };
- // ファイルドロップ時の処理
- $('#drag-area').on('drop', function(e){
- // デフォルトの挙動を停止
- e.preventDefault();
- // ファイル情報を取得
- var files = e.originalEvent.dataTransfer.files;
- uploadFiles(files);
- // デフォルトの挙動を停止 これがないと、ブラウザーによりファイルが開かれる
- }).on('dragenter', function(){
- return false;
- }).on('dragover', function(){
- return false;
- });
- // ボタンを押した時の処理
- $('#btn').on('click', function() {
- // ダミーボタンとinput[type="file"]を連動
- $('#file_selecter').click();
- });
- $('#file_selecter').on('change', function(){
- // ファイル情報を取得
- var files = this.files;
- uploadFiles(files);
- });
- });
- -->
- </script>
- </head>
- <body>
- <div id="drag-area" style="border-style: dashed;background-color: #042943; color: #ffffff;">
- <p>アップロードするファイルをドロップ</p>
- <p>または</p>
- <div class="btn-group">
- <input id="file_selecter" type="file" multiple="multiple" style="display:none;" name="files"/>
- <button id="btn">ファイルを選択</button>
- </div>
- </div>
- <progress value="0" id="prog" max=100></progress>(<span id="pv" style="color:#00b200">0</span>%)
- </body>
- </html>
これで100ファイルまとめて選択してもアップロードできるようになりました。
ただ、1ファイルで8MB以上だとエラーになります。
これに関しては別の対策を考えてみます。
【参考URL】
$.ajaxファイルアップロードでプログレスバーを表示する。
HTML5 進捗状況を表示するプログレスバーを使ってみる
JavaScript で File API を使用してファイルを読み取る
- 関連記事
-
- PHP zipファイルを解凍せずにファイルの内容を読み取る
- jQuery + FileReader APIでファイルを分割し、バイナリでアップロード
- HTML5 + jQueryで複数ファイルのアップロード時、プログレスバーを表示
- CodeIgniter 3 + HTML5 FileAPI + jQueryで複数ファイルのアップロード
- CodeIgniter3 JSONを返すAPIサーバーとして使用する
コメント
管理人のみ閲覧できます
2018/07/15 12:02 by - 編集