2015-10-06 68 views
1

我目前正試圖瞭解亞馬遜S3 web服務的細節。今天的任務是成功下載上傳的圖像(在我的應用中稱爲asset)。我一直在寬鬆地遵循this tutorial中的指導原則,努力從亞馬遜服務器執行直接下載,但似乎沒有任何內容正在下載。使用Rails應用程序下載S3文件

我在我的assets_controller使用get方法如下:

def get 
    asset = current_user.assets.find_by_id(params[:id]) 
    if asset 
     File.open('file.png', 'w') do |file| 
      s3 = AWS::S3::Client.new 
      reap = s3.get_object({bucket_name: ENV['BUCKET'], key: URI.encode(asset.uploaded_file.path)}, target: file) 
     end 

    else 
     flash[:error]="Don't be cheeky! Mind your own assets" 
    end 
    redirect_to assets_path 
end 

我沒有跟這裏的任何錯誤,我的日誌顯示,正在使用正確的鍵。但是,沒有文件下載。必須有我不理解或包括的東西。

一對夫婦的其他問題,這可能有助於

  1. 我不完全知道什麼File.open在這裏所做的事。它與下載的文件有什麼關係?
  2. 我已經添加了redirect_to命令來避免missing_template這會阻止下載被觸發嗎?

回答

3

你看起來是從s3下載文件就好了(到file.png),但你沒有做任何事情,所以它永遠不會做到用戶的瀏覽器。撥打File.open打開下載的數據將進入的文件。

Rails提供了一個send_file方法,它可以做到這一點(這種方法稱爲渲染,因此您不需要在這種情況下調用重定向,否則會出現雙渲染錯誤)。

或者,您可以生成一個簽名鏈接並將用戶重定向到該鏈接。這避免了必須將文件下載到您的服務器。使用SDK我相信你需要使用稍高級別的資源功能,這第2版:

s3 = Aws::S3::Resource.new 
s3.bucket(ENV['BUCKET']).object(object_key).presigned_url(:get, expires_in: 3600) 

生成有效的下載鏈接對象一小時

+0

啊,感謝這麼多;我沒有意識到我必須做一個send_file。我實際上是希望做簽名的鏈接重定向技巧,所以我有幾個問題:「更高級別的資源接口」是什麼意思?另外,我給了上面的'presigned_url'代碼一個鏡頭,並用'未定義的方法'桶'命中'我也用'bucket_name'嘗試了它(因爲我使用'gem'aws-sdk','<2.0' '),那也不好。有什麼想法嗎?再次感謝! – neanderslob

+1

資源接口是你用Aws :: S3 :: Resource(而不是Aws :: S3 :: Client)獲得的,但是這是一個sdk v2的東西 –

+1

嗨,我試圖讓send_file方法正確,但是我一直在下載一個大小爲0字節的文件。我的send_file行如下:'send_file'file.png類型:asset.uploaded_file_content_type'。有什麼明顯的我失蹤了? – neanderslob