質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

2600閲覧

jQueryでファイルを分割してアップロード(POST)する

uer03108

総合スコア194

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2018/12/21 05:39

編集2018/12/21 05:44

下記は、ファイル(テキスト・バイナリ)を分割してサーバにアップロードするコードになります。
所々、記載していない関数がありますが動作は確認済みです。
サーバにはpythonを使用していますが、ここではコードは記載していません。

下記コードでもアップロードは可能なのですが、アップロードの順番がバラバラになってしまって、最終行が途中に書かれていたりと言った不具合が生じてしまいます。
読み取りが完了した(onloadendした)データに元の順番を付けることは可能でしょうか。

または、アップロードの順番を制御することでも大丈夫です。
その場合は、例えば、非同期処理のプロミス関数をN個用意することになるので、「うーん」と言った感じです。

javascript

1 2//ファイルを分割してPOSTする 3let sendData = function(){ 4 5 //ファイルオブジェクト 6 let file = $('#inputFile')[0].files[0]; 7 8 //ファイルサイズ 9 let totalBytes = file.size; 10 11 //ファイル名 12 let fileName = file.name; 13 14 //分割するサイズ(byte) 15 let chunkSize = 8 * 1024; //8kb分割 16 17 //分割数 18 let chunkCount = Math.ceil(totalBytes / chunkSize); 19 20 //読み取り開始バイト 21 let readBytes = 0; 22 23 //ファイル番号 24 let fileNo = 0; 25 26 //ランダム文字列 27 nameRandom = Math.random().toString(36).slice(-10); 28 29 //チャンクサイズごとにスライスしながら読み込み 30 for(let i=0;i<chunkCount;i++){ 31 window.setTimeout(() => { 32 33 //分割ファイル 34 let blob = file.slice(readBytes, readBytes + chunkSize); //stopをオーバーして指定した場合は自動的に切り詰められる 35 36 //読み込み開始バイト 37 readBytes += chunkSize; 38 39 //ファイルリーダー 40 let reader = new FileReader(); 41 42 //onload 43 reader.onloadend = function(evt) { //error : onloadの順番がばらばらで、元の順番が分からない 44 45 //読み取り完了 46 if(evt.target.readyState != FileReader.DONE){ 47 callback(false); 48 return; 49 } 50 51 //読み取ったデータ 52 let dataBase64 = Base64_From_ArrayBuffer(evt.target.result); //array buffer -> base64 53 54 //アップロード 55 localUploadChunkFile(url, blAsync, request, nameRandom, fileNo, chunkCount, dataBase64); 56 57 //更新 58 fileNo++; 59 60 //表示 61 progress(fileNo / chunkCount * 100); 62 63 //終了 64 if(fileNo == chunkCount)callback(true); 65 }; 66 67 //ファイル読み込み 68 reader.readAsArrayBuffer(blob); 69 }), 1 70 }; 71 72} 73

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

クライアントが勝手に分割したのであれば受け取る側がその情報をもとに
合体させる処理が必要でしょう。
サーバー側で各ファイルのサイズと名前を順次受け取り、
最後の送信を受け取った時点で合体させればよいのでは?

あとはpython次第

sample

javascript

1<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 2<script> 3$(function(){ 4 $('[value=up]').on('click', function() { 5 var content = $('#file').prop('files')[0]; 6 var type='application/octet-binary'; 7 var blob=new Blob([content],{type:type}); 8 var fr = new FileReader(); 9 var sep_num=8; 10 var fd=new FormData(); 11 fr.onload = function(e) { 12 var src=e.target.result; 13 src=new Uint8Array(src); 14 src=String.fromCharCode.apply("",src); 15 var sep_size=parseInt(src.length/8)+1; 16 var srcs=new Array(sep_num).fill(null); 17 srcs.forEach(function(x,y){ 18 var sep_file=src.substr(y*sep_size,sep_size); 19 var buffer = new Uint8Array(sep_file.length); 20 for (var i = 0; i < sep_file.length; i++) { 21 buffer[i] = sep_file.charCodeAt(i); 22 } 23 var blob2 = new Blob([buffer.buffer], {type: type}); 24 fd.append($('#file').attr('name')+"[]",blob2,y); 25 }); 26 $.ajax({ 27 "url":"・・・", 28 "type":"post", 29 "data":fd, 30 "cache":false, 31 "processData": false, 32 "contentType": false, 33 }).done(function(data,status,xhr){ 34 console.log(data); 35 }); 36 } 37 fr.readAsArrayBuffer(blob); 38 }); 39}); 40</script> 41<form> 42<input type="file" id="file" name="myfile"> 43<input type="button" value="up"> 44</form>

投稿2018/12/21 05:50

編集2018/12/21 09:27
yambejp

総合スコア114968

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uer03108

2018/12/21 06:56 編集

回答ありがとうございました。 質問の趣旨としては、クライアント側で送信するファイル名(ここではfileNo)が不正確なためにサーバが正しく処理できないといった内容になります。
uer03108

2018/12/21 09:16

再帰を使うことにしました。 メモリリークは大丈夫なのかな。
yambejp

2018/12/21 09:28

PHPerなのでpythonの受け側はよくわからないのですが ファイルを分割して送るsampleをつけておきました 一度試してみて下さい
uer03108

2018/12/21 09:45

有難うございました。 こちらで作成したコードは、頂いたサンプルコードを1つの関数にして、onloadの中で再帰的に呼び出すといった作りになっていると思います。 その様にして1つのファイルを分割してサーバに送信しています。
yambejp

2018/12/21 09:57

filereaderで読んで分割してformdataに格納しまとめて送っています 再帰処理は都度送るということですかね? 合体がめんどくさいかもしれませんね
uer03108

2018/12/21 13:10 編集

そうですね。 サーバ側の合成がめんどくさいです(T_T) 分割してまとめて送っても問題ないのでしょうか。 大容量のファイルは、一回では送れなかったので分割送信することにしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問