19

在过去的几天里,当 google bot 尝试访问我们的主页(欢迎/索引)时,我们开始收到缺少模板的错误。我已经盯着这个看了几个小时,知道我只是错过了一些简单的东西。

A ActionView::MissingTemplate occurred in welcome#index:
Missing template welcome/index with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml, :haml], :formats=>["*/*;q=0.9"], :locale=>[:en, :en]}

但是模板确实存在(index.html.haml)。如果没有,没有人可以访问我们的主页。

以下是一些额外的环境信息:

* REMOTE_ADDR                               : 66.249.72.139
* REMOTE_PORT                               : 56883
* REQUEST_METHOD                            : GET
* REQUEST_URI                               : /

* Parameters: {"controller"=>"welcome", "action"=>"index"}

您的任何见解将不胜感激。

4

4 回答 4

16

这些错误来自GoogleBot 格式化其HTTP_ACCEPTheader的方式。虽然有效(参见 W3 参考),但它添加了一个q=0.6 (最后一个数字可能会更改)用作分隔符。由于没有指定其他媒体类型,这q=0.6不是必需的,我认为这就是 Rails 没有正确处理标头的原因。

(它似乎取决于 Rails 版本。在 Rails 3.0.12 上,它会引发MissingTemplate异常。)

将先前答案中的以下代码添加到相关控制器是不够的:它会以错误响应406

respond_to do |format|
  format.html
end

要在 Rails 3.0.12 下进行这项工作并将某些内容返回给 GoogleBot(比406错误好),您需要添加此代码,以便在检测到-like时将请求的格式设置html为(Rails 将标头值加载到) .*/*;q=0.6HTTP_ACCEPTrequest.format

# If the request 'HTTP_ACCEPT' header indicates a '*/*;q=0.6' format,
# we set the format to :html.
# This is necessary for GoogleBot which perform its requests with '*/*;q=0.6'
# or similar HTTP_ACCEPT headers.
if request.format.to_s =~ %r%\*\/\*%
  request.format = :html
end

respond_to do |format|
  format.html
end

在工作时,此解决方案需要将代码添加到您希望被 GoogleBot 索引的任何控制器操作中,这真的不是 DRY!

为了彻底解决这个问题,我实现了一个小型 Rack 中间件,它做得更好:它检查请求的HTTP_ACCEPT标头,并将任何标头匹配*/*;q=0.6 (数字可能会有所不同)替换为 common */*。这甚至更好,因为q=0.6如果后面没有其他媒体类型,则没有任何意义,因此标头的这种更改不会改变其含义。我们不会强制 Rails 采用任何给定的格式,我们只是告诉它任何可以理解的方式。

您可以在此gist中找到中间件、加载初始化程序和集成测试。

宝石版本在这里: https ://github.com/ouvrages/rails_fix_google_bot_accept

于 2012-04-05T11:07:20.773 回答
6

我也有同样的情况,我做了一些调查,得出的结论是它是 Rails 中的一个“错误”。*/*;q=0.9是 HTTP 接受参数的值。我不确定发生了什么,但在 Rails 3.0 中这是可行的。在 Rails 3.1 中它返回 500 响应,而在 Rails 3.2 中它返回 406 响应。

更新:

关于这个问题有一个开放的错误。一种解决方法是在 Rails 3.1 中设置这个新选项:

config.action_dispatch.ignore_accept_header = true

但是...如果您提供除 HTML 以外的任何页面,您将需要依靠扩展来表示类型(例如/users/1.json)而不是接受标题。

于 2012-01-23T21:10:08.293 回答
4

该问题的解决方案是在您的操作中指定格式。

到目前为止,我的索引操作中只包含以下内容

def index

end

一旦我插入了一个 respond_to 块

def index
  respond_to do |format|
    format.html
  end
end

我不再收到缺少模板的错误。

于 2012-03-14T14:48:18.143 回答
1

您发布的错误中有趣的部分是:formats=>["*/*;q=0.9"]

rails-app 尝试为"*/*;q=0.9"无法使用的格式查找模板。

我猜谷歌以某种方式将其用作格式查询参数,例如welcome?format=*/*;q=0.9

在这些情况下,afaik 最新的 rails 版本只会呈现 406。

于 2012-01-16T17:40:29.087 回答