0

我需要一个按钮来保存当前的网站(就像点击“另存为”一样),我在控制器中创建了一个方法,它适用于任何外部网站(比如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

我也试过 Open URI,同样的问题!

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

我正在使用 rails 3.2 和 ruby​​ 1.9,感谢任何帮助,我已经花了大约 10 个小时试图让它工作!

4

2 回答 2

0

Rails 一次只能处理一个请求。这是两个请求之间永无止境的对峙 - 第一个请求正在等待第二个请求,但第二个请求正在等待第一个请求,因此您会收到超时错误。即使您使用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 回答
0

经过几个小时和许多其他帖子后,我得到了最终解决方案:

Bricker 是对的,因为 Rails 不能在一次调用中多次渲染,取自http://guides.rubyonrails.org/layouts_and_rendering.html “只能渲染或重定向一次操作”

该网站还声明“规则是,如果您没有在控制器操作的末尾显式渲染某些内容,Rails 将自动在控制器的视图路径中查找 action_name.html.erb 模板并渲染它。”

然后,对我来说很好的解决方案是告诉控制器如果在 :params 中设置了下载标志 (download=true) 则呈现为字符串(我还使用 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 回答