如何从 Ruby on Rails 应用程序返回正确的 HTTP 错误代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9130191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:45:27  来源:igfitidea点击:

How to return correct HTTP error codes from Ruby on Rails application

ruby-on-railsrubyhttp

提问by Alexander Savin

I have RoR 3.0 web application which is acting as an OAuth API provider. Now, in API I'd like to return correct HTTP error codes to the API consumer. How do I do this?

我有充当 OAuth API 提供程序的 RoR 3.0 Web 应用程序。现在,在 API 中,我想向 API 使用者返回正确的 HTTP 错误代码。我该怎么做呢?

Here is example:

这是示例:

def destroy_oauth
    @item = Item.find(params[:id])
    if([email protected]? && @item.user_id == current_user.id)
        @item.destroy
        respond_to do |format|
                format.js
                format.xml
        end
    else
        raise ActionController::RoutingError.new('Forbidden')
    end
end

So, in case of error I'm trying to return Forbidden 403 code. Still, when running this I'm getting always 404 Not Found returned. How do I return the correct code?

因此,如果出现错误,我会尝试返回 Forbidden 403 代码。尽管如此,在运行它时,我总是返回 404 Not Found。如何返回正确的代码?

Or is this somehow webserver configurable thing?

或者这是某种网络服务器可配置的东西?

回答by Frederick Cheung

When you're just giving a status code and there is no body, a convenient way is

当你只给出一个状态码而没有正文时,一个方便的方法是

head 403

This method also accepts the symbolic names for status codes, such as

此方法还接受状态代码的符号名称,例如

head :forbidden

回答by Sandip Ransing

You should render page with correct status.

您应该以正确的状态呈现页面。

render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)

回答by gertas

According to ActionController::Head docsjust use this pattern in actions

根据ActionController::Head 文档,只需在动作中使用此模式

  return head([status]) if/unless [some condition here]

Example:

例子:

  return head(:gone) if @record.deleted?
  return head(:forbidden) unless @user.owns?(@record)

returnis used to make sure that no remaining code in the action will be run.

return用于确保不会运行操作中的剩余代码。

回答by Manish Shrivastava

well, you can use

好吧,你可以使用

:status =>500

But, In default Rails take care of the error type rendering itself.

但是,在默认情况下,Rails 会自行处理错误类型的呈现。

Errors default pages are in the public directory. 500.html,404.html etc..

错误默认页面位于公共目录中。500.html,404.html 等。

For more information on :status, how to use it click here

有关:status如何使用它的更多信息,请单击此处

回答by Simon Bagreev

I think you have two problems here: first is that your @item = Item.find(params[:id])line is raising 404 and execution never gets to where intended (ifstatement). Second is that you are raising exceptions and never catch them. Try:

我认为您在这里有两个问题:首先是您的@item = Item.find(params[:id])线路正在引发 404 并且执行永远不会到达预期的位置(if语句)。其次是您正在引发异常并且从不捕获它们。尝试:

def destroy_oauth
   begin
     @item = Item.find(params[:id])
     if([email protected]? && @item.user_id == current_user.id)
       @item.destroy
       respond_to do |format|
          format.js
          format.xml
       end
     else
       raise ActionController::RoutingError.new('Forbidden')
     end
   rescue ActiveRecord::ResourceNotFound
     redirect_to :action => 'not_found', :status => 404 # do whatever you want here
   rescue ActionController::RoutingError
     redirect_to :action => 'forbidden', :status => 403 # do whatever you want here
   end
 end

Something along those lines, but you also mentioned that you are building the API, so when you are rescuing the error, you may want to render xmlerror info. Something like:

沿着这些思路,但你也提到你正在构建 API,所以当你挽救错误时,你可能想要呈现xml错误信息。就像是:

# in application_controller.rb
rescue_from ActionController::RoutingError, :with => :render_forbidden_error

private

def render_forbidden_error(e)
  render :status => e.status, :xml => e
end

Good luck. Udachi.

祝你好运。宇达。