Отсутствует шаблонный блог/индекс в проекте 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/релизы/20110403083651/app/views"
Кажется, кто-то запрашивает изображение с URL-адреса, который не является изображением:
HTTP_ACCEPT "image/jpeg, image/pjpeg, image/png, image/gif"
Любые идеи, что с этим делать? Должен ли я реализовать обработчик для одного из них и вернуть "", чтобы избавиться от этих исключений, или есть лучший способ справиться с этим?
Теперь я получаю следующее:
ActionView:: MissingTemplate: Отсутствует шаблонный блог/индекс с помощью {: formats = > [ "text/*" ],: handlers = > [: rjs,: haml,: rhtml,: erb,: rxml,: builder],: locale = > [: en,: en]} в пути просмотра "/var/www/keeponposting/релизы/20110415040109/app/views"
Нет ли способа отправить обратно HTML независимо от формата запроса?
Ответы
Ответ 1
Я исправил эту проблему (несколько минут назад - пока что так хорошо) с этой новой версией 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
Ответ 2
Я соглашаюсь на блокировку робота-нарушителя, но если вы действительно хотите заставить формат ответа добавить before_filter
и установить request.format = :html
, вот так:
before_filter :force_request_format_to_html
private
def force_request_format_to_html
request.format = :html
end
Ответ 3
Вот более строгий ответ; предложение purp, из обсуждения issue 4127.
class FooController
rescue_from ActionView::MissingTemplate, :with => :missing_template
def missing_template
render :nothing => true, :status => 406
end
end
Ответ 4
У меня возникло бы желание спасти MissingTemplate в вашем контроллере приложений и записать заголовок Referrer, чтобы узнать, что вызывает этот запрос. Вы никогда не знаете, это может быть какая-то неясная часть вашего собственного приложения!
Если, с другой стороны, вы уверены, что это вызвано роботом, рассмотрели ли вы возможность добавить URL-адрес нарушения в файл robots.txt? Например:
User-Agent: YandexImages
Disallow: /your/failed/path
Замена 'your/failed/path' с помощью пути, которым робот спотыкается. Если робот борется повсюду, вы можете просто запретить доступ ко всему сайту для этого конкретного робота:
User-Agent: YandexImages
Disallow: /
Я думаю, что это более чистый и легкий подход, чем внедрение обработчика специально для подавления ошибок от кажущегося плохого бота.
Ответ 5
Я сделал это:
В моем контроллере я поставил фильтр перед:
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 не поддерживаются, он проверяет "/" в заголовке. Если он найдет это, я заставляю рельсы отображать тип mime по умолчанию, игнорируя заголовок accept.
Чтобы проверить это в 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, используя описанные здесь методы , но я обнаружил, что задал запрос. Массив, оба моих теста прошли. Странно, я знаю, но сейчас я перехожу к следующей проблеме.
Ответ 6
Добавить formats: [:html]
для рендеринга:
def action
render formats: [:html]
end