RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

【Ajax】フォームをsubmitせずにバイナリデータをサーバに送りたい

はじめに

こんにちは、@rs_tukkiです。上半期も終わったところでこの六ヶ月のうちに書いた言語を数えてみたところ、実に7つもの言語を触っていたことに気づき驚いています。

さて、先日コードを書いているうちに以下のようなことが必要になりました。

「Web上でファイルを選択したと同時に、そのファイルデータをサーバ上で処理させる」

色々実現方法を考えていたのですが、今回はそのための方法としてAjaxに触れたのでご紹介します。

Ajaxとは

困ったときのWikipedia先生。
Ajax - Wikipedia

Ajax(エイジャックス[1][2]、アジャックス[3])は、ウェブブラウザ内で非同期通信を行いながらインターフェイスの構築を行うプログラミング手法である[4]。 XMLHttpRequest(HTTP通信を行うためのJavaScript組み込みクラス)による非同期通信を利用し、通信結果に応じてダイナミックHTML (DHTML) で動的にページの一部を書き換えるというアプローチを取る[5]。

Ajaxとは、Asynchronous JavaScript + XMLの略語で、JavaScriptの組み込みクラスを使用することで、ページ遷移をすることなく非同期にサーバとやりとりしたり、ページを書き換えたりする手法を指します。
例えば、入力フォームで郵便番号を入力したとき、自動的にその番号に対応する住所を入力してくれる…といったシステムもAjaxを使っていることが多いです。

ファイル選択時に起動するjavascript

さて、今回はJqueryを使ってajaxによるサーバ通信を行い、ファイル選択と同時にそのファイルデータをサーバに送ってみます。

まずはHTML側から。

file.html

<html>
    :
  (中略)
    :
    <input type="file" name="file" onchange="file.fileAttach(this); return false;"/>
    :
  (中略)
    :
</html>

input type="file"は下記のように、何らかのファイルを選択できる入力フォームです。
f:id:rs_tukki:20190930152648p:plain
これにonchange属性を組み合わせることで、フォームの中身が変わったとき、つまりファイルが選択された時に任意のjavascript関数を実行させることができます。

ファイルをバイナリデータにして送信してみる

続いて、今回の肝となるjavascriptの中身を見てみます。
今回、Ajaxの実現にはJqueryajaxメソッドを使用しました。

file.js

fileAttach: function(inputFile) {
        var file = inputFile.files[0]; //ファイルデータを取得
        var url = 'https://hogehoge.co.jp'; //リクエスト先を指定

        var reader = new FileReader();
        var formData = null;
        reader.onload = function() {
            formData = reader.result;
        }
        reader.readAsBinaryString(file);

        setTimeout(() => {
            $.ajax({
                url: url,
                cache: false, //キャッシュを使用しない
                type: "POST",
                data: {
                    "formData": formData,
                },
            }).done(function(data){ //成功時
                console.log("success");
            }).fail(function(){ //失敗時
                console.log("failed");
            });
        }, 500); //少し待ってから実行する
    },

発火元の入力フォームからファイルを取得してきて、それをバイナリデータに変換しています。
FileReaderjavascriptでファイルデータを扱うためのオブジェクトで、今回はonload=読み込みが完了したタイミングでバイナリ文字列を取得しています。
そのデータをパラメータに格納してAjax通信を行うことで、 画面遷移させることなくデータをサーバに送信することが出来ます。

実際に試してみると、サーバ側で以下のようにバイナリ文字列を取得できていることが分かるかと思います。
あとはこれをbyte型に変換してやればOKです。

f:id:rs_tukki:20190930172345p:plain

まとめ

今回は、画面遷移をすることなくサーバへバイナリデータを送信する方法について説明しました。
自分でもまだ勉強が足りないため、もう少し綺麗な方法がある気がしますが…それはまた機会があれば。

参考

Ajax - Wikipedia
$.ajax() | jQuery 1.9 日本語リファレンス | js STUDIO
FileReader.readAsBinaryString() - バイナリ文字列として読み込む | File APIリファレンス

Copyright © RAKUS Co., Ltd. All rights reserved.