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

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

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

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

Q&A

解決済

1回答

964閲覧

サーバー上の.asarファイルをhttpとfsでローカルにダウンロードする方法

dimyas

総合スコア24

Electron

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

0グッド

0クリップ

投稿2022/06/06 14:11

編集2022/06/10 03:33

やりたいこと

  • Webサーバー上にあるasarファイルをNode.jsのfsモジュールとhttpモジュールでローカルにダウンロードしたい
  • requestモジュールで実装していたが、requestは非推奨のため、今後の保守のことも考えfshttp(今後非推奨になることが恐らくない)モジュールだけで実装したい

現状

  • Web記事上にあるfshttpでバイナリ(画像)ファイルをダウンロードする方法のコードを写してasarファイルで試してみたが、createWriteStreamで生成されたファイルに中身がパイプで入れられれいなかった。
  • 上記の方法では画像ファイルは問題なくダウンロードできた

以下コード例

// originalfs = original-fs var downloadFile = function (url, dest, cb) { var file = originalfs.createWriteStream(dest); https.get(url, function (res) { //res.setEncoding('binary'); res.pipe(file); file.on('finish', function () { res.pipe(file); console.log('finish'); file.close(cb); }); }); }; // 変数urlは省略 downloadFile(url, 'rendertest.asar', function (err) { console.log('end'); console.log(err); });

疑問

  • なぜ画像はできたのにasarファイルはできないのか?
  • asarファイルはバイナリファイルではないのか?
  • asarファイルはrequestでしかダウンロードできないのか?
  • node-fetch / axios / got等、どのモジュールでやるのがいいのか?

よろしくお願いいたします。

追加

画像はできたのにasarファイルはできなかった原因について

画像はネット上のもの(普通のサーバーにある)を引っ張ってきたがasarファイルはGoogle Drive上でdrv.twを使いホスティングしていたのが原因

ローカルホストのサーバーからならasarファイルはダウンロードできた。

Google Driveの使用した流れについて

ホスティングしたサイトのURLに行ってファイルをダウンロードしようとすると、このようなページが表示される

イメージ説明

このままだとダウンロードできないので、開発者ツールから「このままダウンロード」のところのformタグのaction属性を見ることにした。

イメージ説明

POSTのフォームタグで、GETのパラメータがあるURLだが、このURLにアクセスしたらファイルがダウンロードできたので、requestモジュールでこのURLを指定してasarファイルをダウンロードすることができた

問題はこのURLでhttp.getでアクセスした時になぜか303のステータスコードになってダウンロードできないことである

このURLでもrequestならダウンロードできたので、303が出ても何かしらの処理をしてダウンロードができる??

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

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

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

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

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

dimyas

2022/06/06 14:25

Electronでフロント部分だけを差し替える、簡易アップデート機能を実装するにあたって、この問題にぶつかりました。
miyabi-sun

2022/06/07 04:22

> node-fetch / axios / got等、どのモジュールでやるのがいいのか? httpでやりたいのか、やりたくないのか どっちなんだい? Node.jsは18系以降Fetchが標準搭載されるのでFetchで良いのでは? https://forest.watch.impress.co.jp/docs/news/1404310.html 今使ってるNode.jsのバージョンがそれ以下なら18系が参考にしているundiciや fetchをNode.jsに持ってくる思想で作られたnode-fetch等で良いでしょうかね
dimyas

2022/06/07 13:28

> httpでやりたいのか、やりたくないのか > どっちなんだい? httpでやりたいです。 それでも無理な場合はfetchでやろうと思います。
dimyas

2022/06/08 22:45

一度asarファイルをローカルホストのサーバーにおいてダウンロードを試してみたらできました。 元々asarファイルはGoogle DriveでDriveToWeb(drv.tw)を使ってホスティングしていたので、それが原因かもしれないです。
miyabi-sun

2022/06/09 01:37

うーむ、だったらサーバがステータスコードでリダイレクトを示す300系を返してる可能性ありますね。 https://developer.mozilla.org/ja/docs/Web/HTTP/Status 多くのダウンロード系のモジュールは300系のリダイレクトがあった場合、 リダイレクト先に接続し直して取得を試みてくれますが、原始的なhttpモジュールだとそこのケアが足りない可能性はあります。
dimyas

2022/06/10 02:34

はい、ステータスコード見てみたら303が返ってきていました
dimyas

2022/06/10 03:37

同じリンクでもrequestモジュールならダウンロードできてたので、何かしらの処理が必要みたいですね それか大きいファイルだとダウンロードに警告のページ挟まれるGoogle Driveじゃなくて、有料のレンタルサーバーや他のホスティングできるサービス使うしかなさそうですね 質問も編集したのでよければ確認お願いします。
miyabi-sun

2022/06/10 04:01

リダイレクトを示す300系のステータスコードの場合 レスポンスの中身に「このURLへ行け」という指示(新しいURL)が入っているはずです。 https://github.com/request/request/blob/master/index.js#L42 https://github.com/request/request/blob/master/index.js#L143 https://github.com/request/request/blob/master/request.js#L285 https://github.com/request/request/blob/master/lib/redirect.js#L45 オブジェクト指向的にごちゃごちゃしててイマイチ追い切れませんが、 requestモジュールには300系ならば、新しいURLに向けてもう一度リクエストを試みるという趣旨のコードが格納されています。 この辺のケアも含めて既存のITエンジニアは既製品のモジュールを使っており こういうhttpみたいなモジュールは使ってないので回答出来ません。 自力で切り開く必要があります。
dimyas

2022/06/10 04:27

レスポンスのheaders.locationに新しいURLが入っていたので、303だった場合はそこからダウンロードするようにすればいけそうです!! ありがとうございます!!
guest

回答1

0

自己解決

結論

このコードでいける

/** * http.get * @param {*} url ダウンロードするファイルのURL * @param {*} outURL 出力するファイルのURL */ const get = (url, outURL) => { const req = https.get(url, (res) => { console.log(res.statusCode); // 303が返ってくる console.log(res.statusMessage); // 303だった場合locationを見てそこから取得 if (res.statusCode === 303) { get(res.headers.location, outURL) // 再帰 return } // ダウンロードした内容をそのまま、ファイル書き出し。 const outFile = originalfs.createWriteStream(outURL); res.pipe(outFile); // 終わったらファイルストリームをクローズ。 res.on('end', function () { console.log('end'); outFile.close(); return }); }); // エラーがあれば扱う。 req.on('error', function (err) { console.log('Error: ', err); return; }); } // get('ダウンロードするファイルのURL', '出力するファイルのURL' )

Google Driveだと303のステータスコードが返ってくるので、その場合はres.headers.locationget()の第一引数に渡してもう一度処理をする。

これから検討すること

  • ネット非接続時などの失敗した時のエラー処理
  • 非同期で実行
  • バージョン管理

追加

エラー処理と非同期処理

const https = require('https') const originalfs = require('original-fs') /** * http.get * asarのダウンロード・置き換え * @param {*} url ダウンロードするファイルのURL * @param {*} outURL 出力するファイルのURL */ const asarDownLoad = async (url, outURL) => { try { return await new Promise((resolve, reject) => { const req = https.get(url, async (res) => { console.log(res.statusCode) // 303が返ってくる console.log(res.statusMessage) // 303だった場合locationを見てそこから取得 if (res.statusCode === 303) { await asarDownLoad(res.headers.location, outURL) // 再帰 resolve(true) //trueを返す return } // ダウンロードした内容をそのまま、ファイル書き出し。 const outFile = originalfs.createWriteStream(outURL) res.pipe(outFile) // 終わったらファイルストリームをクローズ。 res.on('end', () => { console.log('end') outFile.close() resolve(true) // trueを返す }) }) // エラーがあれば扱う。 req.on('error', (err) => { console.log('Error: ', err) reject(false) // falseを返す }) }) } catch (err) { // rejectのfalseをキャッチ console.log(err) return err // falseを返す } } exports.asarDownLoad = asarDownLoad

投稿2022/06/10 14:11

編集2022/06/12 00:09
dimyas

総合スコア24

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問