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

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

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

PDF(Portable Document Format)とはISOによって国際標準として制定されている電子ドキュメント用の拡張子です。

ダウンロード

リモートシステムからローカルシステムへとデータを受信する事、もしくはそのようなデータ転送を行う事をダウンロードと呼びます。

JavaScript

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

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Q&A

解決済

1回答

2268閲覧

jszipを用いたダウンロードで、zip内のファイル名とデータが一致しない

mr.aruru

総合スコア11

PDF

PDF(Portable Document Format)とはISOによって国際標準として制定されている電子ドキュメント用の拡張子です。

ダウンロード

リモートシステムからローカルシステムへとデータを受信する事、もしくはそのようなデータ転送を行う事をダウンロードと呼びます。

JavaScript

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

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

0グッド

0クリップ

投稿2021/05/25 00:09

前提・実現したいこと

 ある条件で抽出された一覧の表に、チェックボックスが設けられており、別途設けたダウンロードボタンを押すと、
チェックボックスにチェックした複数の項目のpdfを、jszipを用いてzipファイルでダウンロードするシステムを作成しています。

発生している問題・エラーメッセージ

 zipファイルにしてダウンロードするところまでは実現出来ているのですが、ダウンロードの1度目だけ、zipファイル内のファイル名と 実際のpdfデータがシャッフルされる(一致しない)という症状が起こっております。  しかし、ダウンロード後に、そのまま再度ダウンロードボタンを押すと、pdfの内容とファイル名が一致してダウンロードされるように なります。  また、さらにその状態で、チェックボックスに新しくチェックを複数追加すると、それまでにチェックしたファイルは問題ないのですが、 追加したファイルのみシャッフルされてダウンロードされ、そのままもう一度ダウンロードボタンを押すと、全てのファイルが正しい名称で ダウンロード出来るようになります。  すべてが1回目で起こる為、原因が掴めずに困っております。  よろしくお願いいたします。

該当のソースコード

javascript

1 2function DLzip(){ 3 var urls=findElements("check"), 4 pdfurls = new Array(), 5 ii=0; 6 7 for (var i=0; i<urls.length; i++){ 8 if (urls[i].checked){ 9 pdfurls[ii]=urls[i].value; 10 ii++; 11 } 12 } 13 batchDownload(pdfurls); 14}; 15 16var batchDownload = function(urlList) { 17 var zip = new JSZip(), 18 ii=0, 19 DLfilename="", 20 deferreds = []; 21 22 for (var i = 0; i < urlList.length; i += 1) { 23 var deferred = downloadFile("../data/" + urlList[i] + ".pdf").done(function(xhr) { 24 var DLfilename = urlList[ii] + ".pdf"; 25 ii++; 26 zip.file(DLfilename, xhr.response); 27 }) 28 deferreds.push(deferred); 29 } 30 31 $.when.apply($, deferreds).done(function() { 32 zip.generateAsync({type:"blob"}).then(function (content) { 33 saveAs(content,"DownloadFile.zip"); 34 }); 35 }); 36}; 37 38var downloadFile = function (url) { 39 var xhr = new XMLHttpRequest(), 40 deferred = new $.Deferred(); 41 42 xhr.addEventListener('load', function() { 43 xhr.response; 44 deferred.resolve(xhr); 45 }); 46 xhr.open('GET', url, true); 47 xhr.responseType = 'arraybuffer'; 48 xhr.send(); 49 return deferred.promise(); 50}

試したこと

  • console.logなどを用いて実際にダウンロードするファイルの場所とファイル名が同じになるかの確認

  ⇒同一であることを確認

  • ブラウザのキャッシュクリア

  ⇒改善されず

  • zipファイルに格納されるファイルの順番

  ⇒チェックしてある上から順に読み取りを確認

  • シャッフルされた際の法則性の確認

  ⇒特定できず

補足情報(FW/ツールのバージョンなど)

  • 抽出方法は、inputタブにname="check"、value="(ファイル名)"を設定し、checkを設定したチェックボックスの中からcheckedに

一致するvalueの情報を読み取り、配列に格納させています。

  • ダウンロードボタンを押すとDLzipが実行されるように設定しています。
  • zipファイルの扱いも含め、ダウンロード系については全く知識がありませんでしたので、こちら

サイトを参考にさせて頂いています。

  • 使用しているブラウザはIEになりますが、Chromeでも確認したところ、同じ症状が起こっています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ダウンロードが非同期処理のため、ダウンロードされる順番と、urlListの順番が一致することが担保されていないように見えるのですが、いかがですか?

投稿2021/05/27 02:44

Lhankor_Mhy

総合スコア36104

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

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

mr.aruru

2021/05/27 08:10

ご回答いただき、ありがとうございます。 お恥ずかしいのですが、今回初めて『非同期処理』という言葉を知り、いくつかのサイトを見てどういう意味なのかは理解できましたが、実際にどのように対応すればよいのかが見えておりません。 『記述の仕方で、非同期処理、同期処理になってしまう』『今回の場合は、同期処理で処理を行えばうまくいく』という認識でよろしいのでしょうか? 参考にしたソースを理解することも急務ではあるのですが、下記のサイトを参考に手を付けてみたのですが、どのように書き直せばいいのかが分かりません。 一部だけでも構いませんのでアドバイスを頂けますと幸いです。 https://blog.proglearn.com/2020/11/03/%e3%80%90js%e3%80%91%e5%90%8c%e6%9c%9f%e5%87%a6%e7%90%86%e3%81%a8%e9%9d%9e%e5%90%8c%e6%9c%9f%e5%87%a6%e7%90%86%e3%81%ae%e9%81%95%e3%81%84%e3%81%a8%e3%81%af%ef%bc%9f%e4%be%8b%e3%81%88%e8%a9%b1%e3%82%92/
Lhankor_Mhy

2021/05/27 08:23

非同期処理とは、メインの処理と同期的ではなく行われる処理のことです。 ですので、 for (var i = 0; i < urlList.length; i += 1) {...} のループが終わった時には、 downloadFile(...)の処理はひとつも終わっていません。 また、それぞれの downloadFile(...) も別々に行われるので、その処理が終わる順番が保証されないです。 --- つまりたとえば、 [a.pdf, b.pdf] とあって、 a.pdfがすごく重いファイルでダウンロードに1分かかり、 b.pdfが軽いファイルでダウンロードに1秒しかかからない場合、 var DLfilename = urlList[ii] + ".pdf"; の処理は、b.pdf→a.pdfの順番で行われます。 しかし、iiは処理された順番で0→1と増えるので、urlList[0]→urlList[1]、つまり、a.pdf→b.pdfという順番で処理されているためにずれが起きているのではないか、と推測しています。 --- 解決方法ですが、クロージャまたはスコープを試してみてはどうでしょうか。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures#creating_closures_in_loops_a_common_mistake 具体的には for (let i = 0; i < urlList.length; i += 1) { として、ii を使うのをやめるといいのではないかと思います。
mr.aruru

2021/06/03 01:09

お返事、遅くなりまして申し訳ございません。 丁寧にご回答頂き、ありがとうございます。 まずは、シャッフルされた状態で登録されてしまうという原因を理解することが出来ました。 まだ、動作するものは完成していませんが、あとは、紹介して頂いたリンクを参考にして勉強させて頂きます。 ありがとうございました!
Lhankor_Mhy

2021/06/03 05:13

お役に立てたようで何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問