【问题标题】:Internal server error 500 on missing image file (Rails 3.2.12)缺少图像文件时出现内部服务器错误 500 (Rails 3.2.12)
【发布时间】:2013-02-24 10:20:16
【问题描述】:

如果我们请求伪造的图像文件,Rails 会生成内部 500 服务器错误而不是 404。请参阅下面的日志。

这是 routes.rb 中捕获 404 的行:

# Catches all 404 errors and redirects
match '*url' => 'default#error_404'

其他未知 URL 使用 404 正确处理。图片文件和带有文件扩展名的 URL 有什么不同?

Started GET "/images/doesnotexistyo.png" for 71.198.44.101 at 2013-03-08 07:59:24 +0300
Processing by DefaultController#error_404 as PNG
  Parameters: {"url"=>"images/doesnotexistyo"}
Completed 500 Internal Server Error in 1ms

ActionView::MissingTemplate (Missing template default/error_404, application/error_404 with {:locale=>[:en], :formats=>[:png], :handlers=>[:erb, :builder]}. Searched in:
  * "/home/prod/Prod/app/views"

【问题讨论】:

    标签: ruby-on-rails actionview


    【解决方案1】:

    DefaultController 是什么?该控制器正在处理 404,而不是 Rails 默认响应:

    ActionController::RoutingError (No route matches [GET] "/images/doesnotexistyo.png"):
    

    所以找出这个控制器,error_404正在执行,没有找到模板default/error_404,因此出现500错误。

    您的代码中可能有类似的代码:

    rescue_from ActiveRecord::RecordNotFound, :with => :error_404
    

    【讨论】:

    • 我们在 routes.rb 中用捕获 404 的行更新了 q。问题是为什么它适用于某些 URL 而不是带有文件扩展名的 URL(尤其是图像)?
    • 方法error_404的内容是什么?该方法即将结束,并尝试使用提供的格式:png 使用 erb 或 builder 呈现视图。除非您有 error_404.png.erb 或 error_404.png.builder,否则您将在应用程序现在的设置方式中看到此错误。
    • 啊,我明白了。在 3.2.12 中处理这个(以及一般的 404)的正确方法是什么?要回答您的问题,error_404 是一个空操作,仅呈现相应的 .html.erb 视图。
    【解决方案2】:

    问题是Default控制器内部的error_404方法不能处理png格式的请求。当您要求 JSON 响应时,您可以构建一个类似于以下内容的 URL:

    /controller/action.json
    

    在动作里面你会有类似的东西

    def action
      respond_to do |format|
        format.html # Renders the default view
        format.json { render :json => @model }
        format.xml { render :xml => @model }
      end
    end
    

    如您所见,它指定了如何处理 JSON 和 XML 请求,但是由于没有 format.png,因此该操作无法处理 .png 格式。添加这个:

    format.png # Handle the request here...
    

    希望对你有帮助:)

    编辑

    添加这个以重定向到您的 404 处理程序:

    def error_404
      respond_to do |format|
        format.html
        format.png { redirect_to :controller => 'default', :action => 'error_404' }
      end
    end
    

    干杯:)

    编辑2

    使用此代码捕获各种请求:

    def error_404
      respond_to do |format|
        format.html { render :not_found_view }
        format.all { redirect_to controller: 'default', action: 'error_404' }
      end
    end
    

    用您的 404 页面替换 :not_found_view。这将为 html 请求呈现 404 页面,并为任何其他类型的请求重定向到 self(使用 html 格式)。

    希望对你有帮助:)

    【讨论】:

    • 谢谢!如果它不是 HTML 格式,我们可以强制它呈现 HTML 视图并显示正确的 404 页面吗?
    • 编辑了我的答案,希望对您有所帮助:D
    • 我们如何设置一个包罗万象的?换句话说,如果我们想捕获任何文件扩展名(例如,.jpg、.gif)而不单独指定每个扩展名,我们将如何处理它?
    • format.any 在我们尝试渲染 404 操作时不起作用。
    • 对不起,我的错。 format.any 需要一堆格式作为参数,然后是一个块来处理这些格式,你可以阅读它here。我会在找到全面的解决方案后尽快与您联系。
    【解决方案3】:

    也许不适合你,但由于我在控制器中动态地对页面进行了一些最终检查,所以我只需按照我的所有 404'ing 来处理非 html 文件:

    format.all { render :status => 404, :nothing => true }
    

    【讨论】:

      猜你喜欢
      • 2013-09-04
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多