前回
HTML5とJavascriptとファイルビュアーを作ってみた。 で
ローカル上にあるファイルの表示をしてみました。
今回はそのファイルをサーバーにアップロードして、アップロード先のURLを返してもらう
ファイルアップローダーを作ってみようと思います。
それでは、本編です。
ローカル上にあるファイルの表示をしてみました。
今回はそのファイルをサーバーにアップロードして、アップロード先のURLを返してもらう
ファイルアップローダーを作ってみようと思います。
それでは、本編です。
目次
目標
Ajaxでファイルをアップロードして、保存先を返すファイルアップローダーを作る。
サンプルコード
ファイルは3つ。フロントのtest014-1.htmlとtest014css.cssと
Ajax応答するのtest014-Reception.cgidです。
test014-1.html
<!DOCTYPE html>
<html>
<head>
<meta content="IE=edge"
http-equiv="X-UA-Compatible" />
<link href="./test014css.css"
rel="stylesheet"
type="text/css" />
<title>Selecters</title>
<script type="text/javascript">
function updateAjax(formid,uploadfileid){
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = collupdate;
xmlHttp.open("POST",
"http://[サーバーのアドレス]/cgi-bin/test014-Reception.cgi",
true);
let form = new FormData(document.getElementById(formid));
let upfileob = document.getElementById(uploadfileid);
if(upfileob.files[0]!=null){
xmlHttp.send(form);
}
}
function collupdate(){
if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
var obj = JSON.parse(xmlHttp.responseText);
alert(xmlHttp.responseText+ "更新されました");
var str = xmlHttp.responseText;
var obj = JSON.parse(str);
document.getElementById("viewerserver").innerHTML
+= obj.filename
+ "<div><img class=\"photo\" src=\"http://[サーバーのアドレス]/"
+ obj.filename
+ "\" /></div>\n";
}
}
//ファイルAPIで選択したファイルを指定のタグへ追加する関数
//第一引数inputタグのID
//第二引数取り込んだファイルのファイル名の表示先となるID
//第三引数取り込んだファイルの表示先になるID
function view(uploadfileid,filenameid,viewerid){
//各オブジェクト取得
var upfileob = document.getElementById(uploadfileid);
var filename = document.getElementById(filenameid);
var viewer = document.getElementById(viewerid);
if(upfileob.files[0]!=null){
upfileob.disabled="disabled";
filename.innerHTML = upfileob.files[0].name;
if(upfileob.files[0].type=="image/jpeg" ||
upfileob.files[0].type=="image/png"){
//FileReaderオブジェクト作成
var filereader = new FileReader();
//ファイルロード後のコールバック関数定義
filereader.onload = function(e){
viewer.innerHTML
+= "<img class=\"photo\" src=\""
+ filereader.result
+ "\" />\n";
upfileob.disabled="";
}
//ファイル読み込み
filereader.readAsDataURL(upfileob.files[0]);
}
else if(upfileob.files[0].type=="text/plain"){
//FileReaderオブジェクト作成
var filereader = new FileReader();
//ファイルロード後のコールバック関数定義
filereader.onload = function(e){
viewer.innerHTML
+= "<div>"
+ filereader.result;
+ "</div>";
upfileob.disabled="";
}
//ファイル読み込み
filereader.readAsText(upfileob.files[0],"shift-jis");
}
else{
viewer.innerHTML
+= "<div>.jpeg,.png,.txt以外受付できません。</div>";
upfileob.disabled="";
}
}
else{
filename.innerHTML = "<div>ファイルが未選択です。</div>";
}
}
//view関数で処理した内容をリセットする関数
//第一引数inputタグのID
//第二引数取り込んだファイルのファイル名の表示先となるID
//第三引数取り込んだファイルの表示先になるID
function reset(uploadfileid,filenameid,viewerid){
//各オブジェクト取得
var upfileob = document.getElementById(uploadfileid);
var filename = document.getElementById(filenameid);
var viewer = document.getElementById(viewerid);
upfileob.value = null;
filename.innerHTML = "<div>ファイルが未選択です。</div>";
viewer.innerHTML ="";
}
</script>
</head>
<body>
<div class="container">
<main>
<div id="myfileapi">
<label id="myfilename" for="myuploadfile"></label>
<label id="myfileapibutton" for="myuploadfile">
ファイル選択
</label>
<label id="myfileapireset"
onclick="reset('myuploadfile','myfilename','viewer');">
リセット
</label>
<form enctype="multipart/form-data" id="sendform"
method="post"> --ポイント!
<input type="file" name="uploadfile" id="myuploadfile"
onchange="view('myuploadfile','myfilename','viewer');" />
</form>
</div>
<div>
<button type="button"
onclick="updateAjax('sendform','myuploadfile');">
ファイルをアップロード
</button>
</div>
<div id="viewer"></div>
<div id="viewerserver"></div>
</main>
</div>
</body>
</html>
|
test014.css
div{
margin: 10px;
}
#myfileapibutton{
display: table-cell;
width: 100px;
height: 30px;
background-color: #FD8080;
font-size: 15px;
text-align: center;
vertical-align: middle;
border-radius: 3px;
margin: 5px;
}
#myfileapireset{
display: table-cell;
width: 100px;
height: 30px;
background-color: #FD8080;
font-size: 15px;
text-align: center;
vertical-align: middle;
border-radius: 3px;
margin: 5px;
}
#myfilename{
display: table-cell;
width: 200px;
height: 30px;
text-align: left;
vertical-align: middle;
border-radius: 3px;
margin: 5px;
background-color: #CCCCCC;
}
#myuploadfile{
display: none;
}
.photo{
width:200px;
}
|
test014-Reception.cgi
#!/usr/bin/python
# -*- coding: utf-8 -*-
from os import environ
from datetime import datetime
import fcntl
import io
import cgi
import hashlib
Forms = cgi.FieldStorage()
Keys = Forms.keys()
mustkeys=["uploadfile"]
Filename = "";
#保存するファイル名を作成
NewFileName = hashlib.md5( \
datetime.now().strftime("%Y/%m/%d %H:%M:%S") \
).hexdigest();
#Postの要素の個数が、必須の要素の個数と同一であることを確認
if ( len(set(mustkeys) - set(Keys)) == 0):
#必要なpostの要素があること、要素が空ではないことを確認
if( not( Forms["uploadfile"].value == "")):
#レスポンス用のファイルのパス文字列を作成
Filename = 'html/tmp/'+ NewFileName +"."+ \
Forms["uploadfile"].filename.split(".")[1];
#ファイル保存先のパス文字列を作成
target ="../html/tmp//" + NewFileName +"."+ \
Forms["uploadfile"].filename.split(".")[1];
with open(target,"wb") as file:
fcntl.flock(file.fileno(), fcntl.LOCK_EX);
try:
file.write(Forms["uploadfile"].value);
finally:
fcntl.flock( file.fileno(), fcntl.LOCK_UN);
#JSONデータの作成・出力
json1 = '''Content-Type: application/json; charset=utf-8
{'''
json2 = '"filename": "' + Filename +'"}'
print json1+json2
|
実行例-表示例
test014-1.htmlにアクセスして操作します。
ファイルを選択して「ファイルをアップロード」ボタンを押すことでアップロードを実行
応答を取得するとポップアップしサーバー側のURLを利用して画像を表示します。
ファイルを選択して「ファイルをアップロード」ボタンを押すことでアップロードを実行
応答を取得するとポップアップしサーバー側のURLを利用して画像を表示します。
ポイント!
終わりに
今回はファイルアップローダを作ってみました。
さまざまなアップローダーがありますが、
「こういった感じで動くんだな(サービス展開するならいろいろと仕込む必要はあるはずですが・・・)」
というイメージが持てたので、非常に勉強になりました。
最近フロント側でいろんなギミックを作ることを勉強していたので、
サーバーサイドのPythonでいささか手間取りましたが、
サクサクと動いてくれて満足です。
参考になれば幸いです。
ご利用は自己責任で!
さまざまなアップローダーがありますが、
「こういった感じで動くんだな(サービス展開するならいろいろと仕込む必要はあるはずですが・・・)」
というイメージが持てたので、非常に勉強になりました。
最近フロント側でいろんなギミックを作ることを勉強していたので、
サーバーサイドのPythonでいささか手間取りましたが、
サクサクと動いてくれて満足です。
参考になれば幸いです。
ご利用は自己責任で!
0 件のコメント:
コメントを投稿