提问人:Masa Sakano 提问时间:10/31/2022 更新时间:11/3/2022 访问量:266
Rails button_to 在 W3C 验证器中失败
Rails button_to fails with W3C validator
问:
Ruby-on-Rails 的输出最近在 W3C 验证中开始失败,返回的消息如下:button_to
具有 type 属性且值为隐藏的输入元素不得具有值为 on 或 off 的自动完成属性。
所以我想摆脱这个错误。
Rails-7.0.4 中 View (ERB) 中的相应语句是button_to
<%= button_to "Add Entry", new_article_path, form_class: "inline_form button_to",
method: :get, params: { a_token: "abc" } %>
生成 HTML(简化!
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="utf-8"> <title>My Title</title> </head>
<body>
<form class="inline_form button_to" method="get" action="/articles/new?locale=en">
<input type="submit" value="Add Entry" />
<input type="hidden" name="a_token" value="abc" autocomplete="off" />
</form>
</body>
</html>
如果我将其粘贴到 W3C 验证器表单中,它会失败并显示上述消息。
显然,W3C 验证器不喜欢带有 .但这是(在 Rails 7.0 中)的默认输出。autocomplete
input
type="hidden"
button_to
似乎 Rails 团队去年添加了 Rails 输出,以根据 Rails 存储库中的问题 #42610 使 HTML 输出成为 Firefox 证明。在相关的讨论中,用户 jpwynn 表示 (2021-06-27) 该更改不会破坏 W3C 验证。但现在似乎确实如此......autocomplete=off
据我所知,我没有修改过我的 Rails 应用程序中的相关部分。然而,我注意到常规测试在 W3C 验证中已经开始失败。所以,我怀疑 W3C 最近更改了规范(但我可能错了!
我的 Rails 测试非常简单,如下所示,使用 Gem w3c_validators Ver.1.3.7;它只是检测任何错误,如果有任何错误,则失败:
# /test/test_helper.rb
require 'w3c_validators'
def my_w3c_validate
arerr = @validator.validate_text(response.body).errors
assert_equal 0, arerr.size,
"Failed in W3C-validation: ("+arerr.map(&:to_s).join(") (")+")"
end
跟:Gemfile
group :development, :test do
gem 'w3c_validators', '~> 1', '>= 1.3.6' # => 1.3.7 in reality
end
那么,Rails 的输出是有效的 HTML 吗?如果没有,我该如何修改它以使输出 HTML 成为有效的 HTML?
我使用的是最新的稳定版本,Rails-7.0.4。button_to
答:
W3C HTML 检查器(验证器)的维护者@sideshowbarker善意地提供了信息(请参阅问题中的评论)。
总结如下:
- W3C HTML 检查器做得绝对正确:
无效。<input type="hidden" name="abc" autocomplete="off">
根据 HTML 表单规范,
当佩戴自动填充锚斗篷时,autocomplete 属性(如果指定)必须具有一个值,该值是一组有序的空格分隔标记,仅由自动填充详细信息标记组成(即不允许使用“on”和“off”关键字)“ — 其中”穿着自动填充锚斗篷
这基本上应用于标签。
<input type=hidden>
- 新的检查项是最近(2022-10-26)在检查器上实现的,因此最近我的 Rails W3C 测试结果发生了变化。请参阅 Git 拉取请求
- Rails 方法生成的 HTML 违反了标签的规范。
button_to
<input>
- 具有讽刺意味的是,最近(去年)的 HTML 生成发生了变化,以应对 Firefox 的不当行为;当时它确实通过了 W3C HTML 验证!参见 Rails Github Issue #42610
button_to
- 具有讽刺意味的是,最近(去年)的 HTML 生成发生了变化,以应对 Firefox 的不当行为;当时它确实通过了 W3C HTML 验证!参见 Rails Github Issue #42610
现在,由于 W3C 验证器运行正常,您有两种选择:
- 改变 Rails 生成 HTML 的方式
button_to
- 在这方面修改 W3C 验证的结果,以便验证不会因为此错误而失败,并且您仍然可以使用所有其他验证。
这是第二项策略中的措施。您传递 的 Array,此方法返回相同的 Array,但删除了上述错误。原始相关错误消息可以记录在 中。我也把脚本(但有更广泛的描述)放在 Github Gist 中。W3CValidators::Message
Logger
# @example Usage, maybe in /test/test_helper.rb
# # Make sure to write in /config/environments/test.rb
# # config.ignore_w3c_validate_hidden_autocomplete = true
# #
# #require 'w3c_validators'
# errors = @validator.validate_text(response.body).errors
# errors = _may_ignore_autocomplete_errors_for_hidden(errors, "W3C validaiton failed: ")
# assert_empty errors, "Failed in W3C validation: "+errors.map(&:to_s).inspect
#
# @param errs [Array<W3CValidators::Message>] Output of [email protected]_text(response.body).errors+
# @param prefix [String] Prefix of the warning message recorded with Logger.
# If empty, no message is recorded in Logger.
# @return [Array<String>]
def may_ignore_autocomplete_errors_for_hidden(errs, prefix="")
removeds = []
return errs if !Rails.configuration.ignore_w3c_validate_hidden_autocomplete
errs.map{ |es|
# Example of an Error:
# ERROR; line 165: An “input” element with a “type” attribute whose value is “hidden” must not have an “autocomplete” attribute whose value is “on” or “off”
if /\AERROR\b.+\binput\b[^a-z]+\belement.+\btype\b.+\bhidden\b.+\bautocomplete\b[^a-z]+\battribute\b/i =~ es.to_s
removeds << es
nil
else
es
end
}.compact
ensure
# Records it in Logger
if !removeds.empty? && !prefix.blank?
Rails.logger.warn(prefix + removeds.map(&:to_s).uniq.inspect)
end
end
评论
<input type="hidden" name="a_token" value="abc" autocomplete="off" />
完成
属性(如果指定)必须有一个值,该值是一组有序的空格分隔标记,仅由自动填充细节标记组成(即不允许使用”on“和”off“关键字)”——其中“佩戴自动填充锚斗篷”仅表示元素具有属性。input
type=hidden
<input>
autocomplete="off"
input
type="hidden"