0

現在のWebサイトを保存するためのボタンが必要です([名前を付けて保存]をクリックするのと同じように)。コントローラーでメソッドを作成しました。これは、外部サイト(http://www.google.comなど)でうまく機能しますが、アプリケーション内のサイトでは機能しません。タイムアウトエラーが発生します。これは私には説明がありません:(

問題は何ですか?

#CONTROLLER FILE
def save_current_page
  # =>  Using MECHANIZE
  agent = Mechanize.new
  page = agent.get request.referer
  send_data(page.content, :filename => "filename.txt")
end

私もOpenURIを試しましたが、同じ問題です!

#CONTROLLER FILE
def save_current_page
 # => USANDO OPEN URI
 send_data(open(request.referer).read, :filename => "filename.txt")
end

私はrails3.2とruby1.9を使用していますが、助けていただければ幸いです。すでに10時間ほどかけて動作させています。

4

2 に答える 2

0

数時間と他の多くの投稿の後、私は最終的な解決策に到達しました:

http://guides.rubyonrails.org/layouts_and_rendering.html「アクションごとに1回だけレンダリングまたはリダイレクトできる」からわかるように、Railsが1回の呼び出しで複数回レンダリングすることはできないという点でBrickerは正しいです。

このサイトには、「コントローラーアクションの最後に明示的に何かをレンダリングしない場合、Railsはコントローラーのビューパスでaction_name.html.erbテンプレートを自動的に検索してレンダリングするという規則があります」とも記載されています。

次に、私にとってうまく機能した解決策は、ダウンロードフラグ(download = true)が:paramsに設定されている場合に文字列にレンダリングするようにコントローラーに指示することでした(アプリケーションの任意のビューから機能させるためにrequest.urlも使用します)。

意見:

= link_to 'Download', request.url+"&downloadexcel=true", :class => 'btn btn-primary btn-block'

コントローラ:

def acontrolleraction
  #some controller code here
  if params[:downloadexcel]
    save_page_xls
  else
    # render normally
  end
end


def save_page_xls
  #TRESCLOUD - we create a proper name for the file
  path = URI(request.referer).path.gsub(/[^0-9a-z]/i, '')
  query = URI(request.referer).query.gsub(/[^0-9a-z]/i, '')
  filename = @project_data['NOMBRE']+"_"+path+"_"+query+".xls"

  #TRESCLOUD - we render the page into a variable and process it
  page = render_to_string

  #TRESCLOUD - we send the file for download!
  send_data(page, :filename => filename, :type => "application/xls")
end

ヒントをありがとう!

于 2012-10-16T23:39:24.753 に答える
0

Rails は一度に 1 つのリクエストしか処理できません。これは、2 つの要求の間で終わりのないスタンドオフです。最初の要求は 2 番目の要求を待っていますが、2 番目の要求は最初の要求を待っているため、タイムアウト エラーが発生します。Passenger などでアプリの複数のインスタンスを実行している場合でも、それは悪い考えです。

それを回避するために私が考えることができる唯一の方法は、次のような条件文を使用することです。

referer = URI.parse(request.referer)

if Rails.application.config.default_url_options[:host] == referer.host
  content = "via yoursite.com"
else
  agent = Mechanize.new
  page = agent.get request.referer
  content = page.content
end

send_data content, filename: "filename.txt"

少し汚れていますが、タイムアウトの問題を回避する必要があります。自分のサイトからページの実際のコンテンツを取得する限り、それはあなた次第です。テンプレートをレンダリングするか、キャッシュから何かを取得するか、単に無視することができます。

より良い解決策は、このコードを Resque や Delayed Job などにエンキューすることです。その後、キューはリクエストを作成し、通常どおりページをリクエストするために順番に待機できます。また、アプリケーションがリモート リクエストを行う間、ユーザーが待機する必要がないことも意味します。これは、ページが応答するのにどれくらいの時間がかかるかを誰が知っているかを考えると危険です。

于 2012-10-01T04:53:49.783 に答える