XMLHttpRequestを使ったファイルアップロード(multipart/form-data)

javascript

XMLHttpRequestを使ったファイルアップロード(multipart/form-data)

前回の投稿ではXMLHttpRequestを使ったファイルアップロードを試しました。
その際、formの属性に「enctype=”multipart/form-data”」を記述しない形で試しました。

では、multipart/form-dataを記述する場合はどのような場合なのかを
今回は試してみようと思います。

multipart/form-dataを付与する必要がある場合というのは、
フォームの項目が、ファイルの選択と、それ以外のテキスト入力や、
チェックボックス、ラジオボタン、セレクトボックス、等の通常よく使われるフォーム項目がある場合、
それらとファイル送信を併用してサーバに通信する時です。

multipart/form-dataを記載することにより、サーバ側でファイル情報の他、
その他フォーム情報を受信して処理することができます。

前回の投稿を少し変更して、下記のようなHTMLを用意しました。

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

<form id="testform" enctype="multipart/form-data">
	<div>
		<input type="text" name="text1" id="text1">
	</div>
	<div>
		<input type="text" name="text2" id="text2">
	</div>
	<div>
		<input type="text" name="text3" id="text3">
	</div>
	<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);

?>

上記の記述はファイルの受信しか行っていませんが、

実際には、$_FILES の HTTPファイルアップロード変数の他、
$_REQUESTの HTTPリクエスト変数にも「text1」「text2」「text3」の変数の値が渡ってきていることがわかります。

コメントを残す

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