2019-12-11に更新

XMLHTTPRequestでファイルを複数回に分けてアップロードしたい

初めて質問させていただきます。
JavaScriptのXMLHTTPRequestを使ってテキストファイルをサーバへアップロードしようとしています。

Webサーバー側は小さいプアなハードウェアのマイコン基板で、1回にPOST送信できるデータ量が2Kバイト以下という制限があるため1行ずつまたは複数行をブロックにして複数回で送る必要があります。
POSTの完了を確認して次のPOST作業へ進みたいのですが、JavaScriptではそのような順序通りの処理が簡単にはできないようです。
複数回に分けるPOSTはどうやれば成功するのか、いろいろトライしてXMLHTTPRequestの送信関数をsetIntervalで定期的に呼び出すという、おそらくかなり乱暴なやり方で実現しました。

しかし、これでは時間的なロスが大きいのと失敗の確率も高いようです。
インターネットへの接続もないので、IE11では promise は使うことができません。

良い方法があれば教えていただけないでしょうか?
JavaScriptのコードです

function send_file(o){
    var uploadFile = document.getElementById('upload_file');
    var file = uploadFile.files[0];     // HTML本体のファイル入力枠でファイルを指定
    var xhr = new XMLHttpRequest(); 
    var lines;              // 行の配列として使用
    var xStatus = 0;    // POST送信の状態
    var linenum = 0;    // 行番号
    var SendString = '';    // 送信する本文の文字列
// POST送信の関数
    var SendLineFunc = function() { 
        xhr.open('POST', 'upload_file.cgi', true);       // XMLHttpRequestのオープン、サーバ側のCGIを指定
        xhr.timeout = 1000; 
        xhr.responseType = 'text'; 
        xhr.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8'); 
        xhr.onreadystatechange = function() { 
            if (xhr.readyState === XMLHttpRequest.DONE){ 
                if (xhr.status === 200) {
                    if(linse === lines.length)       // ファイル全行を送れば完了とする
                        xStatus = 1; 
                }"
                else
                    xStatus = 2;    // 送信のエラーで終了させる
            }"
        }; "
        SendString='LineNo='+lines[linenum]; 
        xhr.send(SendString); 
        linenum++;
    }; 
// ファイルの読み込み開始
    if (!file){
        alert('Please select a firmware object file.');
    }
    else{
        var uploadText = document.getElementById('upload-text'); 
        var reader = new FileReader(); 
        console.log('-reading-'+file.name); 
        reader.readAsText(file); 
// ファイルの読み込み完了にてテキストファイルを行配列 Lines に読み込み、1行ずつのPOSTを開始する
        reader.onload = function () { 
            uploadText.innerHTML = reader.result; 
            lines = reader.result.split('\\n'); 
            console.log('---file read complate--- Lines = '+lines.length); 
            var id = setInterval(function(){ // インターバルの設定
                SendLineFunc();         // 250mSEC間隔でPOSTの関数を呼び出す
                if(xStatus > 0){           // 送信のステータスが終了状態になればインターバル処理は終了
                    clearInterval(id); 
                }}, 250);
        }; 
    } 
}
ツイッターでシェア
みんなに共有、忘れないようにメモ

eokayama

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント