Rails 7.1新sanitizer下如何允许ActionText自定义标签?
Rails 7.1 中允许 ActionText 嵌入 iframe(如YouTube视频)的解决方案
在Rails 7.0及更早版本,我们可以通过给ActionText::ContentHelper.allowed_tags添加iframe来解决ActionText sanitizer移除iframe标签的问题,但Rails 7.1重构了HTML sanitizer体系,原有代码会因ActionText::ContentHelper未定义而报错。以下是两种可行的解决方式:
方案一:适配默认的HTML5 Sanitizer
Rails 7.1默认采用HTML5 sanitizer,其标签和属性权限是Set类型,需用add方法配置。在config/initializers/action_text.rb中添加:
Rails.application.config.after_initialize do sanitizer = ActionText::ContentHelper.sanitizer if sanitizer.is_a?(Rails::Html::Sanitizer) # 允许iframe标签 sanitizer.class.allowed_tags.add("iframe") # 放行iframe所需的核心属性,可按需增减 %w[src width height frameborder allowfullscreen].each do |attr| sanitizer.class.allowed_attributes.add(attr) end end end
方案二:继续使用旧版HTML4 Sanitizer
若要保留和旧版本一致的sanitizer行为,可先指定使用Legacy sanitizer,再配置允许的标签:
- 在
config/application.rb中添加sanitizer配置:
config.action_text.sanitizer = Rails::Html::LegacySanitizer
- 在
config/initializers/action_text.rb中添加标签和属性放行规则:
Rails.application.config.after_initialize do if defined?(ActionText::ContentHelper) ActionText::ContentHelper.allowed_tags << "iframe" %w[src width height frameborder allowfullscreen].each do |attr| ActionText::ContentHelper.allowed_attributes << attr end end end
安全优化建议
为避免恶意iframe嵌入,建议给iframe的src添加域名白名单。以HTML5 sanitizer为例,可在初始化代码中添加过滤逻辑:
Rails.application.config.after_initialize do sanitizer = ActionText::ContentHelper.sanitizer if sanitizer.is_a?(Rails::Html::Sanitizer) sanitizer.class.allowed_tags.add("iframe") sanitizer.class.allowed_attributes.add("src") # 仅允许YouTube域名的iframe sanitizer.class.before_sanitize_element do |env| node = env[:node] if node.name == "iframe" && node["src"] allowed_domains = ["https://www.youtube.com/", "https://youtu.be/"] unless allowed_domains.any? { |domain| node["src"].start_with?(domain) } node.remove end end end end end
内容的提问来源于stack exchange,提问作者Cimm
相关产品推荐
相关产品推荐

