Rails 3 发送数据问题; 生产环境和开发环境的区别

3

我在我的Rails 3应用程序中遇到了一个奇怪的错误。我使用以下代码来发送不公开的图像:

image = open(f, "rb") { |io| io.read }
send_data(image, :disposition => 'inline')

我正在使用这段代码在管理页面和用户页面显示图片。如果我使用开发环境,这段代码可以正常工作,并且图片可以在两个页面中显示。但是如果我使用生产环境,这些图片只会在管理页面显示,而不会在用户页面显示。我可以点击未显示的图片,并选择“属性”。在图像类型下,我看到:

application/xhtml+xml

但其他公共图像是以JPG图像/PNG图像或类似格式存在的。

环境之间的差异会导致图像无法正常工作,我该如何修复此问题,以便在所有页面上正确显示这些图像?


看看这些文档,它们提到了许多可能出错的事情:http://apidock.com/rails/ActionController/DataStreaming/send_file。 - Jakub Hampl
问题出在应用程序代码(在过滤器之前)的访问限制上,这是我的情况。一个朋友帮我修复了它 :) - nikicc
1
你可以将你的修复方法作为答案添加,这样其他人也可以从你的问题中学习 :) - Taryn East
在我的情况下,问题出在糟糕的代码编写上。我使用了 before filters 来检查用户是否可以查看页面。在这个 before filter 中,我有一个 redirect_to,它将请求重定向到前端页面。因此,当浏览器发送图片请求时,它会被 before filter 重定向到前端页面。这就是为什么类型是 HTML 的原因。很抱歉之前没有写过,但由于这是我的代码中的错误而不是 Rails 的问题,所以我没有回应。但我仍然不知道这在开发中是如何工作的?!?! - nikicc
1个回答

0

我曾经有过类似的症状。我知道这是一个旧问题,已经解决了,但我想贡献一下我的发现,因为我的情况是由不同的原因引起的。

我正在构建一个CSV文件,并使用send_file将文件发送到浏览器。在开发中它运行得很好,在生产中浏览器报告页面未找到。

以下是控制器中的操作。

def export
  @campaign = LiveEmailCampaign.find params[:id]
  @campaign.recipients_csv do |csv_file|
    send_file csv_file,
      filename: @campaign.name,
      type: Mime::CSV 
  end 
end

而CSV是从模型中的此代码构建的。

def recipients_csv
  tempfile = Tempfile.new(self.name.downcase.dasherize)
  CSV.open tempfile, 'w' do |csv|
    recipients.each do |recipient|
      csv << [recipient]
    end
  end
  yield tempfile
end

经过几分钟的研究,我确定问题在于生产服务器上Apache中XSendFile指令与用于写入CSV数据的临时路径之间的冲突。 在我的情况下,XSendFile仅设置为应用程序根目录,而临时文件位于服务器上的 /tmp。
为了避免在服务器级别调整 XSendFile 配置,我只需指示 Tempfile 使用 Rails 应用程序中的 tmp 文件夹。
因此,我将模型方法中对 Tempfile 的调用更改为:
tempfile = Tempfile.new(self.name.downcase.dasherize)

现在,Rails和Apache再次成为朋友。我只需要重构这段代码,因为它没有显式地取消链接创建的临时文件。最佳实践是显式取消链接临时文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接