web-dev-qa-db-ja.com

Node.js ExpressアプリでGET応答としてリモートURLからファイルを送信する方法

コンテキスト:Expressを使用した多層Node.jsアプリ。フロントエンドはAzure Webサイトとしてホストされ、バックエンドデータはParseから取得されます。

GETエンドポイントがあり、ユーザーエクスペリエンスをファイルのダウンロードにしたい。ファイルがフロントエンドと同じサーバーにある場合は、

res.sendfile(localPath);

ただし、ファイルは別のサーバー上のバックエンドによってホストされており、フロントエンドが知っているのはURLだけです。だから私は現在やっています:

res.redirect(externalURL);

これにより、ブラウザがアセットファイルのURL(動画)に移動し、ブラウザに表示されます。私が知りたいのはブラウザに代わりにそのファイルをダウンロードさせ、同じページに留まる方法

私はこれについてしばらく探していましたが、最初にファイルをフロントエンドの一時ファイルにダウンロードしないと、その方法がわかりません。これはおそらくHTTP 101のものなので、どんな助けにも感謝します!

21
BillyRayCyrus

http.request() 関数を使用してexternalURLにリクエストを送信し、次に pipe() レスポンスを返すことができますresに。 pipe()を使用すると、サーバーを介してブラウザにファイルがストリーミングされますが、ディスクに保存されることはありません。 (ブラウザに表示されるだけでなく)ファイルもダウンロードする場合は、 content-disposition header を設定する必要があります。

これは、Googleロゴを「ダウンロード」するサーバーの例です。これは標準のhttpモジュールを使用しているだけで、表現はしていませんが、基本的には同じように機能するはずです。

var http = require('http');

http.createServer(function(req, res) {
    var externalReq = http.request({
        hostname: "www.google.com",
        path: "/images/srpr/logo11w.png"
    }, function(externalRes) {
        res.setHeader("content-disposition", "attachment; filename=logo.png");
        externalRes.pipe(res);
    });
    externalReq.end();
}).listen(8080);

request モジュールを使用する場合は、さらに簡単です。

var http = require('http'),
    request = require('request');

http.createServer(function(req, res) {
    res.setHeader("content-disposition", "attachment; filename=logo.png");
    request('http://google.com/images/srpr/logo11w.png').pipe(res);
}).listen(8080);

注:ブラウザが保存するファイルの名前は、filename=ヘッダーのcontent-dispositionの部分で設定されます。この場合は、logo.pngに設定します。

40
Mike S