我的Rails应用程序中有一个正常的HTML前端和一个JSON API。现在,如果有人拨打/api/not_existent_method.json
,它将返回默认的HTML 404页面。有什么方法可以将此改为{"error": "not_found"}
之类的东西,同时保留HTML前端的原始404页面完好吗?需要在Rails中返回JSON格式的404错误
回答
一个朋友指出我朝着优雅的解决方案,它不仅可以处理404也是500错误。事实上,它处理每一个错误。关键是,每一个错误都会产生一个异常,通过一堆机架中间件向上传播,直到它们中的一个被处理。如果你有兴趣了解更多,你可以看this excellent screencast。 Rails拥有自己的异常处理程序,但您可以通过配置文件exceptions_app
配置选项覆盖它们。现在,你可以写你自己的中间件,或者你可以路由错误回到轨道,就像这样:
# In your config/application.rb
config.exceptions_app = self.routes
然后你只需要这些路线在您的config/routes.rb
匹配:
get "/404" => "errors#not_found"
get "/500" => "errors#exception"
然后你只需创建一个控制器来处理这个。
class ErrorsController < ActionController::Base
def not_found
if env["REQUEST_PATH"] =~ /^\/api/
render :json => {:error => "not-found"}.to_json, :status => 404
else
render :text => "404 Not found", :status => 404 # You can render your own template here
end
end
def exception
if env["REQUEST_PATH"] =~ /^\/api/
render :json => {:error => "internal-server-error"}.to_json, :status => 500
else
render :text => "500 Internal Server Error", :status => 500 # You can render your own template here
end
end
end
要添加的最后一件事:在开发环境中,rails通常不呈现404或500页,而是打印回溯。如果您想在开发模式下看到您的ErrorsController
正在运行,请在config/enviroments/development.rb
文件中禁用回溯功能。
config.consider_all_requests_local = false
当然,这将是这个样子:
class ApplicationController < ActionController::Base
rescue_from NotFoundException, :with => :not_found
...
def not_found
respond_to do |format|
format.html { render :file => File.join(Rails.root, 'public', '404.html') }
format.json { render :text => '{"error": "not_found"}' }
end
end
end
NotFoundException
是不异常的真实姓名。它会随着Rails版本和你想要的确切行为而变化。使用Google搜索很容易找到。
感谢您的想法,但我正在使用Rails 3.2.2,其中异常处理发生了变化。这将不再有效。 – iblue 2012-04-20 21:38:15
@iblue这在Rails 3.2+中工作得很好,是更好的解决方案。有关更多信息,请参阅'rescue_from' [docs](http://apidock.com/rails/v3.2.3/ActiveSupport/Rescuable/ClassMethods/rescue_from)。 – Intelekshual 2012-08-07 17:42:00
它只适用于404错误,而不适用于500错误。 – iblue 2012-08-07 18:38:21
尝试把你routes.rb
结束:
match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }
对于读这个的人来说,Rails.application.routes文件中的'match'现在要求你通过'via:'参数指定HTTP方法。当您尝试使用上述行时,这也会显示为错误。 – sameers 2017-07-22 18:32:58
我喜欢创建一个单独的API控制器,其设置格式(JSON)和特定的API的方法:
class ApiController < ApplicationController
respond_to :json
rescue_from ActiveRecord::RecordNotFound, with: :not_found
# Use Mongoid::Errors::DocumentNotFound with mongoid
def not_found
respond_with '{"error": "not_found"}', status: :not_found
end
end
RSpec的测试:
it 'should return 404' do
get "/api/route/specific/to/your/app/", format: :json
expect(response.status).to eq(404)
end
这似乎只适用于记录。你如何管理'api/non_existant_route'的情况? – Sebastialonso 2015-02-22 14:05:50
'rescue_from ActiveRecord :: RecordNotFound,with:not_found'需要'with::not_found',但它只是一个字符编辑:P – erroric 2015-05-08 20:03:17
@erroric thanks! :) – 2015-05-10 17:57:39
- 1. 错误函数不返回JSON格式
- 2. Rails ajax不返回json格式
- 3. mySql表返回需要为iPhone格式化的JSON UITableview
- 4. AngularJs $ resource.save返回404错误
- 5. UrlFetchApp返回错误404
- 6. 图片返回404错误
- 7. Facebook sdk.js返回404错误
- 8. trace.axd返回404错误
- 9. JSON返回格式
- 10. 与格式帮助需要返回
- 11. Twitter API返回错误:需要SSL(92)
- 12. 在现有目录返回404错误
- 13. Elmah报告不需要的404错误
- 14. 需要帮助JSON格式
- 15. 如何在wcf中返回json格式
- 16. WCF服务返回JSON格式的错误
- 17. Rails 3:如何在JSON请求中返回错误?
- 18. Django的 - 返回JSON,错误
- 19. 需要表格格式的Json结果
- 20. 格式函数返回错误的值
- 21. iphone:NSDateFormatter返回错误的格式
- 22. RequestContext为我的imagaes返回404错误?
- 23. JSON键值在Python中返回错误
- 24. JSON返回格式cordys BOP
- 25. API:仅返回JSON格式
- 26. jQuery的获取返回404错误,但仍然返回回答
- 27. 格式化时间需要API错误
- 28. 类型错误:格式需要映射
- 29. curl get json返回404
- 30. JSON文件返回404
另外,不要忘记添加状态码到渲染。否则你的客户端/浏览器不会知道它是一个404/500。 render:text =>“404 not found”,:status =>:not_found – arnab 2012-08-03 04:46:54
我编辑了我的答案。 – iblue 2012-08-03 10:02:34
我会说一个respond_to块在渲染函数中更普遍: respond_to do | format | format.json {render json:{error:“not-found”}。to_json,status:404} format.html {render text:“404 Not found”,status:404} end – 2013-04-19 16:11:11