我的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. htaccess需要時返回500錯誤404
- 2. 如何在Rails 4中返回404 JSON格式?
- 3. 錯誤函數不返回JSON格式
- 4. Rails ajax不返回json格式
- 5. mySql表返回需要爲iPhone格式化的JSON UITableview
- 6. UrlFetchApp返回錯誤404
- 7. RequestMapping返回404錯誤
- 8. Mod_rewrite返回404錯誤
- 9. Facebook sdk.js返回404錯誤
- 10. NuGet.Server返回404錯誤
- 11. AngularJs $ resource.save返回404錯誤
- 12. Django返回404錯誤
- 13. Yii返回exception.CHttpException.404錯誤
- 14. jQuery AJAX返回404錯誤
- 15. 圖片返回404錯誤
- 16. trace.axd返回404錯誤
- 17. 捲曲返回404錯誤
- 18. Rails:用json返回錯誤消息
- 19. JSON返回格式
- 20. 與格式幫助需要返回
- 21. Swagger返回xml格式,而不是json.I需要json格式來查看
- 22. 返回JSON錯誤
- 23. Twitter API返回錯誤:需要SSL(92)
- 24. Rails的回報所有404和500錯誤,JSON
- 25. Elmah報告不需要的404錯誤
- 26. Highrise API正在返回404錯誤
- 27. 在現有目錄返回404錯誤
- 28. 需要幫助JSON格式
- 29. WCF服務返回JSON格式的錯誤
- 30. 需要表格格式的Json結果
另外,不要忘記添加狀態碼到渲染。否則你的客戶端/瀏覽器不會知道它是一個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