tag:crieit.net,2005:https://crieit.net/users/eokayama/feed eokayamaの投稿 - Crieit Crieitでユーザーeokayamaによる最近の投稿 2019-12-11T13:43:05+09:00 https://crieit.net/users/eokayama/feed tag:crieit.net,2005:PublicArticle/15599 2019-12-11T13:36:05+09:00 2019-12-11T13:43:05+09:00 https://crieit.net/posts/XMLHTTPRequest-5df07235e765e XMLHTTPRequestでファイルを複数回に分けてアップロードしたい <p>初めて質問させていただきます。<br /> JavaScriptのXMLHTTPRequestを使ってテキストファイルをサーバへアップロードしようとしています。</p> <p>Webサーバー側は小さいプアなハードウェアのマイコン基板で、1回にPOST送信できるデータ量が2Kバイト以下という制限があるため1行ずつまたは複数行をブロックにして複数回で送る必要があります。<br /> POSTの完了を確認して次のPOST作業へ進みたいのですが、JavaScriptではそのような順序通りの処理が簡単にはできないようです。<br /> 複数回に分けるPOSTはどうやれば成功するのか、いろいろトライしてXMLHTTPRequestの送信関数をsetIntervalで定期的に呼び出すという、おそらくかなり乱暴なやり方で実現しました。</p> <p>しかし、これでは時間的なロスが大きいのと失敗の確率も高いようです。<br /> インターネットへの接続もないので、IE11では promise は使うことができません。</p> <p>良い方法があれば教えていただけないでしょうか?<br /> JavaScriptのコードです</p> <pre><code>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); <span>}</span><span>}</span>, 250); }; } } </code></pre> eokayama