WEBサイトでページ遷移をせずにファイルをアップロードする方法(サンプルソース付)

2018年6月26日

Javascript テクノロジー プログラミング

インターネットサイトを作った時に、データをアップロードする仕様にしたい場合、inputタグのtype="file"を使って、パソコン内のデータをアップロードできます。 その際に、PWAを意識したようなシステムであったり、何かしらのインタラクティブ性の高いWEBサイトの場合、submitした後で、ページのloadingが入ってしまうのがよろしくない場合があります。 そんな時に使えるテクニックを紹介します。

こんな時に使える

1. 画像リストを表示しているようなサイトで画像アップロードをする時に、毎回ページを再ロードされたくない場合。 2. 縦に長い情報量の多いページで、表示編集するような機能を追加して、文中に画像を挿入するような仕様を設けた場合 3. メールサービスのような機能をWEBブラウザで作った場合、添付ファイルなどをデータ送信する場合に、ページをリロードしないようにサーバーにアップロードさせたい場合

ソースコード

下記4ファイルを同じ階層に設置し、phpが利用できる環境でindex.htmlにアクセスすると、アップロードができるようになります。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Data-upload</title> <script src="upload.js"></script> </head> <body> <button class="data-upload">ファイルをアップロード</button> <div id="timer"></div> <script> var start = (+new Date()); setInterval(function(){ var timer = document.getElementById("timer"); var sec = parseInt(((+new Date()) - start)/100 , 10) / 10; timer.innerHTML = sec +" sec"; },30); </script> </body> </html> ;(function(){ var custom = { uploadFileMulti : true, // 複数ファイルアップロード [true:複数ファイル false:単一ファイル] attribute:{ iframeId:"dataUploadIframe", inputFileId:"input_file", inputFileName:"data[]", buttonName:"data-upload", actionPath:"./upload.php", iframeSrc:"./upload.html" } }; var $$ = function(){ switch(document.readyState){ case "complete": this.set(); break; case "interactive": this.setEvent(window , "DOMContentLoaded" , $$.prototype.set); break; default: this.setEvent(window , "load" , $$.prototype.set); break; } }; $$.prototype.set = function(){ $$.prototype.setIframe(); $$.prototype.setButton(); }; $$.prototype.setButton = function(){ var buttons = document.getElementsByClassName(custom.attribute.buttonName); for(i=0; i<buttons.length; i++){ this.setEvent(buttons[i] , "click" , $$.prototype.clickButton); } }; $$.prototype.clickButton = function(){ var doc = document.getElementById(custom.attribute.iframeId).contentWindow.document; var input = doc.getElementById(custom.attribute.inputFileId); input.click(); }; $$.prototype.setIframe = function(){ var iframe = document.createElement("iframe"); iframe.id = custom.attribute.iframeId; iframe.style.setProperty("display","none",""); iframe.src = custom.attribute.iframeSrc; iframe.onload = $$.prototype.makeForm; document.body.appendChild(iframe); }; $$.prototype.makeForm = function(e){ var form = document.createElement("form"); form.name = "fm"; form.method = "POST"; form.enctype = "multipart/form-data"; form.action = custom.attribute.actionPath; this.contentWindow.document.body.appendChild(form); var inp = document.createElement("input"); inp.id = custom.attribute.inputFileId; inp.type = "file"; inp.name = custom.attribute.inputFileName; if(custom.uploadFileMulti === true){ inp.multiple = "multiple"; } inp.onchange = $$.prototype.dataUpload; form.appendChild(inp); }; $$.prototype.dataUpload = function(){ var doc = document.getElementById(custom.attribute.iframeId).contentWindow.document; var fm = doc.forms[0]; fm.submit(); }; $$.prototype.setEvent = function(target, mode, func){ if (target.addEventListener){target.addEventListener(mode, func, false)} else{target.attachEvent('on' + mode, function(){func.call(target , window.event)})} }; new $$; window.$$UPLOAD = $$; })(); <?php namespace UPLOAD; class PROC{ public static $saveFolder = "upload/"; public static function getRequest(){ self::checkFolder(); $dt = date("YmdHis"); for($i=0,$c=count($_FILES["data"]["tmp_name"]); $i<$c; $i++){ $fileInfo = pathinfo($_FILES["data"]["name"][$i]); $filePath = self::$saveFolder . $dt."-".$i. "." .$fileInfo["extension"]; move_uploaded_file($_FILES["data"]["tmp_name"][$i] , $filePath); } } public static function checkFolder(){ if(!is_dir(self::$saveFolder)){ mkdir(self::$saveFolder , 0777, true); return "make"; } return "exist"; } } // echo "-test-"; \UPLOAD\PROC::getRequest(); <html> <head></head> <body></body> </html>

使い方

1. 対象のページに下記2ファイルを設置
upload.js upload.php
2. HTMLにjsファイルをscriptタグで記述
<script src="upload.js"></script>
3. アップロードを行うボタンを設置 ボタンのclass名に「data-upload」を追加

解説

動作 : アップロードされたファイルは「upload」フォルダが自動で作られてそこに格納されます。 カスタマイズ : デフォルトで複数ファイルのアップデートができるようになっていますが、upload.jsファイルの冒頭customの"uploadFileMulti"をtrueからfalseに切り替えると、単一ファイルだけしかアップロードできなくなります。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。