XMLHttpRequestを使ったファイルアップロード

javascript

XMLHttpRequestを使ったファイルアップロード

XMLHttpRequestを使ったファイルアップロードを試してみます。

HTML側のファイル参照ボタンは

<input type="file" name="file1">

のように書くものとします。
(場合により、このファイル参照用ボタンにはidやclassを指定して使います)

また、XMLHttpRequestには仕様策定のバージョンがあり、XMLHttpRequest の Level2 の
sendメソッドを使用するとファイルのアップロードができます。

ユーザがブラウザから

<input type="file" name="file1">

を使って選択したデータにはファイル情報が格納されます。

具体的には、参照ボタンからファイルを選択した結果としてFileListオブジェクトを取得し、
また、ドラッグ&ドロップ操作時にはDataTransferオブジェクトのfilesプロパティを使って取得できます。

通常のHTML+php等でファイルアップロードをする場合は、
formに「 enctype=”multipart/form-data”」の属性を記述しますが、
今回試したサンプルでは、上記の属性を記述していません。

簡単なサンプルを書いて試してみます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>

<form id="testform">
	<div>
		<input type="file" name="file1" id="file1">
	</div>
	<div>
		<input type="button" id="sample_file_upload" value="ファイルアップロードのテスト">
	</div>
</form>

<div>通信時の処理内容</div>
<div id="ajax_result"></div>

<script type="text/javascript">

// ファイルアップロードボタンのDOMを取得
let element_sample_file_upload = document.getElementById('sample_file_upload');

// イベントを付与
element_sample_file_upload.addEventListener('click',  SendXMLHttpRequest, false);

// ボタン押下時の処理
function SendXMLHttpRequest()
{

	// 通信処理を画面に出力する為、操作用DOMの取得
	let result = document.getElementById("ajax_result");
	result.innerHTML += 'ファイルアップロードのテスト start' + '<br />';
	result.innerHTML += '通信処理の開始' + '<br />';

	// フォーム内容の取得
	let testform_data = document.getElementById("testform");

	// 送信用データ
	let form_data = new FormData(testform_data);

	// 通信用XMLHttpRequestを生成
	let req = new XMLHttpRequest();

	// POST形式でサーバ側の「response.php」へデータ通信を行う
	req.open("POST", "response.php");

	// ファイルが選択されたときに処理を実行するようイベントリスナーに登録
	input_file = document.getElementById("file1");
	input_file.addEventListener('change', function(e) {
		form_data.append('file1', e.target.files[0]);
	});

	// ファイル送信
	req.send(form_data);

	// 通信が完了したらレスポンスをコンソールに出力する
	req.addEventListener('readystatechange', () => {
		// ここでレスポンス結果を制御する
		console.log("レスポンス結果");
	});

	result.innerHTML += '通信処理の終了' + '<br />';
	result.innerHTML += 'レファイルアップロードのテスト end' + '<br />';
}

</script>

</body>
</html>

サーバ上のHTMLはこちら(test1.html)

このように書くことで、選択したファイルをサーバ側へ送信することができます。
ファイルをアップロード後のサーバサイドでは、ファイルを受信するプログラムを用意します。

言語はなんでもいいのですが、上記のサンプルを動作させる為にphpで下記のように書きました。

<?php

// ファイルのアップロード処理
if (is_uploaded_file($_FILES["file1"]["tmp_name"])) {
	if (move_uploaded_file($_FILES["file1"]["tmp_name"], "./datas/" . $_FILES["file1"]["name"])) {
		chmod($_FILES["file1"]["name"], 0644);
		$ret = true;
		$message = $_FILES["file1"]["name"] . "をアップロードしました。";
	} else {
		$ret = false;
		$message = "ファイルをアップロードできません。";
	}
} else {
	$ret = false;
	$message = "ファイルが選択されていません。";
}

// 処理結果をjson形式用の形にまとめる
$json_value = array(
	"ret" => $ret,
	"message" => $message
);

// ヘッダーの指定と返却値をjsonで返す
header("Content-Type: application/json; charset=UTF-8");
header("X-Content-Type-Options: nosniff");
echo json_encode($json_value, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);

?>

実際に試してみると、選択したファイルがサーバにアップロードされることがわかります。

また、ファイルアップロード後のレスポンス結果を処理する部分は、何も処理を書いていません。

javascriptのXMLHttpRequestを使ってファイルを送信する方法を試した程度なので、
実際の開発では、レスポンス結果を制御して実装する必要があります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です