2017-11-28 8 views
0

私は別のサーバからファイルをダウンロードするためのリンクを持ったレールアプリケーションを持っています。 実際のファイルのURL /場所が「容易に」検出されないようにしたい。Rails:別のサーバからファイルをダウンロードする(ファイルを読むことなし)

send_fileを使ってみましたが、これはローカルファイルでのみ動作するようです。

私はsend_dataで試してみました。これは最初にファイルを読み込んだときにのみ動作します(例:file.open ...)。ファイルの一部が非常に大きいので、ファイルを読み込まずに送信できるようにしたいのですが、ユーザーのフィードバックなどはありません。

基本的に、私は単純に直接ファイルURLへのリンク/提供:ブラウザからダウンロードが開始され、ブラウザから開始されます。

私が言いましたように、コントローラを使って(send_file/dataメソッドを使用して)私のダウンロードを処理したいのは、ファイルの場所を「容易に」検出できるようにすることです。

私は十分にこのことを説明しました:)何かアドバイス

乾杯、 ジョンのための

感謝を願っています。

答えて

1

公開URLからクライアントにデータを読み込まずにデータをストリーミングする場合は、それをクライアントに送信したい場合は、何とかそれを読まなければなりません。ここではリダイレクトが最適な解決策ですが、パブリックURLが醜いためリダイレクトは嫌です。

Net :: HTTP read_body(列挙型を生成する)からresponse_body(列挙型を受け入れる)をストリーミングできます。それはあなたのメモリフットプリントを維持するかもしれません。

def DownloadController 
    def show 
    source = URI('http://www.example.com/some-big-pdf.pdf') 

    # Tell the client to download the response with given filename 
    headers['Content-Disposition'] = 'attachment; filename="some-big-pdf.pdf"' 

    Net::HTTP.start(source.host, source.port) do |http| 
     req = Net::HTTP::Get.new source 

     http.request(req) do |res| 
     self.response_body = res.read_body 
     end 
    end 
    end 
end 

は編集:もちろんsend_dataうちもバッファから読み取ることができます。

http.request(req) do |res| 
    send_data res.read_body, filename: 'some-big-pdf.pdf', disposition: 'download' 
end 

しかし、この完了するまで、ワーカープロセスをタイアップされることに注意してください。同時ダウンロードを処理するのに十分な人員がいることを確認する必要があります。また、Railsの内部ではなく、Webサーバ(NGINX?)内で上流の処理を調べることもできます。

これらの方法の詳細については、Net::HTTP#read_bodyおよびActionController::Metal#response_body=を参照してください。も参照してくださいhttps://coderwall.com/p/kad56a/streaming-large-data-responses-with-rails

+0

お返事と情報ありがとう!これは小さなファイルには効果的ですが、大きなファイルに対しては(ファイルの内容を読むと思われます)ハングします。ブラウザからダウンロードを開始するだけでよいので、ユーザーは少なくともブラウザのUIコンポーネントなどからダウンロードの進行状況を見ることができます。 単純にhrefからサーバー/ファイルを指す場合と同じ動作です。 –

+0

'send_data'を試しましたか?これは 'self.response_body ='よりも速く走っていました。 –

+0

はい、私はsend_dataを試みました、その遅い:)(私は大きなファイルを持っています)...基本的に、私はそれを開く/ファイルを最初に読むことなくダウンロードを開始したい。 –

関連する問題