缺少Ruby on Rails项目上的模板博客/索引

对于我的一个项目,我偶尔得到这个例外:

ActionView :: MissingTemplate:缺少模板博客/索引{:handlers => [:rxml,:erb,:builder,:rjs,:haml,:rhtml],:formats => [“image / jpeg”,“image / pjpeg“,”image / png“,”image / gif“],:locale => [:en,:en]}在视图路径”/ var / www / keeponposting / releases / 20110403083651 / app / views“

似乎有人从不是图像的URL请求图像:

HTTP_ACCEPT“image / jpeg,image / pjpeg,image / png,image / gif”

有什么想法可以做些什么吗? 我是否必须为其中一个实现处理程序并返回“”以消除此exception或是否有更好的方法来处理它?

现在我也得到了这个:

ActionView :: MissingTemplate:缺少模板博客/索引{:formats => [“text / *”],:handlers => [:rjs,:haml,:rhtml,:erb,:rxml,:builder],:locale => [:en,:en]}在视图路径“/ var / www / keeponposting / releases / 20110415040109 / app / views”

无论请求的格式是什么,都没有办法发回HTML?

我用这个新的Rails 3.1选项修复了这个问题(几分钟前 – 到目前为止,这么好):

config.action_dispatch.ignore_accept_header = true 

如本Rails问题所述 。 这在config/application.rb

我在RSpec请求测试(使用Capybara)中测试了它:

 it "should not break with HTTP_ACCEPT image/*;w=320;h=420 from iPhone" do page.driver.header "Accept", "image/*;w=320;h=420" visit "/some/path" page.should have_content("Some content") end 

我同意阻止有问题的机器人,但如果你真的想强制响应格式,请添加一个before_filter并设置request.format = :html ,如下所示:

 before_filter :force_request_format_to_html private def force_request_format_to_html request.format = :html end 

这是一个更严格的回应; 关于问题4127的讨论, purp的建议。

 class FooController rescue_from ActionView::MissingTemplate, :with => :missing_template def missing_template render :nothing => true, :status => 406 end end 

我很想在应用程序控制器中解救MissingTemplate并记录Referrer标头以查看触发此请求的内容。 你永远不知道,它可能是你自己的应用程序的一些模糊的部分!

另一方面,如果您确信这是由机器人引起的,您是否考虑过将有问题的URL添加到robots.txt文件中? 例如:

 User-Agent: YandexImages Disallow: /your/failed/path 

用机器人绊倒的路径替换“你的/失败/路径”。 如果机器人在整个地方挣扎,你可能只是不允许访问该特定机器人的整个站点:

 User-Agent: YandexImages Disallow: / 

我认为这比实现一个专门用于抑制看似表现不佳的机器人的错误的处理程序更简洁明了。

我这样做了:在我的控制器中,我放了一个前filter:

 def acceptable_mime_type unless request.accepts.detect{|a| a == :json || a == :html} || request.accepts.include?(nil) if request.accepts.detect{|a| a.to_s().include?("*/*")} ActionDispatch::Request.ignore_accept_header = true else render text: "Unacceptable", status: 406 false end end end 

它检查我支持的类型(例如json,html)和nil(nil呈现默认html),然后如果不支持这些mime类型,它会检查标题中的“ / ”。 如果找到它,我强制rails通过忽略accept头来呈现默认的mime类型。

要在rspec中测试这个,我必须这样做:

 describe 'bad header' do describe 'accept' do let(:mimeTypes) { ["application/text, application/octet-stream"] } it 'should return a 406 status code' do request.accept = mimeTypes get 'index' expect(response.response_code).to eq 406 end describe 'with */* included' do it 'should return a 200 status code' do request.accept = ["*/*"] + mimeTypes get 'index' expect(response.response_code).to eq 200 end end end end 

出于某种原因,我在尝试使用此处描述的方法在rspec中正确发送接受标头时遇到问题,但我发现如果将request.accept设置为Array,则我的测试都会通过。 很奇怪,我知道,但我现在正在继续讨论下一期。

添加formats: [:html]渲染:

 def action render formats: [:html] end