You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rails(ActionText)的Trix编辑器中允许iframe或原始HTML内容?

如何在Rails(ActionText)的Trix编辑器中允许iframe或原始HTML内容?

嗨,我来帮你解决这个问题!不用急着切换到其他编辑器,Trix + ActionText完全可以实现你要的功能,而且能做到干净又安全——毕竟你已经确认只有可信管理员使用这个表单,我们只要针对性放开权限并做好过滤就行。

整体思路

核心要做两件事:一是让Trix编辑器在粘贴时不转义你允许的iframe内容,二是让Rails后端处理ActionText内容时,不会把这些iframe过滤掉,同时只保留来自YouTube/Vimeo的合法链接。

第一步:修改Trix的前端粘贴行为

Trix默认会转义所有粘贴的HTML,所以我们需要给编辑器加一个粘贴事件监听器,手动处理iframe内容:

在你的JavaScript控制器文件里(比如app/javascript/controllers/action_text_controller.js)添加这段代码:

document.addEventListener("trix-paste", function(event) {
  const clipboardHtml = event.clipboardData.getData("text/html");
  if (!clipboardHtml) return;

  // 解析粘贴的HTML内容
  const parser = new DOMParser();
  const doc = parser.parseFromString(clipboardHtml, "text/html");
  const iframes = doc.querySelectorAll("iframe");
  if (iframes.length === 0) return;

  // 阻止默认粘贴行为,避免Trix转义内容
  event.preventDefault();

  const editor = event.target.editor;
  iframes.forEach(iframe => {
    const src = iframe.src;
    // 只保留YouTube和Vimeo的iframe
    if (src.includes("youtube.com/embed") || src.includes("player.vimeo.com/video")) {
      editor.insertHTML(iframe.outerHTML);
    }
  });
});

这段代码会在用户粘贴HTML时,自动提取其中的iframe,检查来源是否是你允许的平台,符合条件的就直接插入编辑器,不会被转义。

第二步:自定义ActionText的内容清理器

ActionText默认会过滤掉iframe这类标签,所以我们需要自定义一个清理规则,允许iframe同时限制它的合法来源:

  1. 在app/lib目录下创建custom_action_text_sanitizer.rb文件:
class CustomActionTextSanitizer < Rails::Html::Sanitizer
  def initialize
    super
    @whitelist_sanitizer = Rails::Html::WhiteListSanitizer.new(
      # 保留默认允许的标签,再加上iframe
      tags: Rails::Html::WhiteListSanitizer.allowed_tags + %w[iframe],
      # 给iframe添加允许的属性
      attributes: Rails::Html::WhiteListSanitizer.allowed_attributes.merge(
        "iframe" => %w[src width height frameborder allowfullscreen]
      )
    )
  end

  def sanitize(html, options = {})
    # 先通过默认白名单过滤
    sanitized_html = @whitelist_sanitizer.sanitize(html, options)
    # 再进一步过滤iframe的src,只保留合法域名
    doc = Nokogiri::HTML.fragment(sanitized_html)
    doc.css("iframe").each do |iframe|
      src = iframe["src"]
      unless src&.match?(/\Ahttps?:\/\/(www\.youtube\.com\/embed|player\.vimeo\.com\/video)/)
        iframe.remove
      end
    end
    doc.to_html
  end
end
  1. 在config/initializers/action_text.rb中配置ActionText使用这个自定义清理器:
Rails.application.config.action_text.content_sanitizer = CustomActionTextSanitizer.new

第三步:验证渲染效果

做完上面的配置后,当管理员粘贴合法的YouTube/Vimeo iframe HTML时,Trix会直接插入正确的内容,后端也会保留这个iframe并限制来源,最后在视图中用<%= @your_model.your_rich_text_field %>渲染时,就会正常显示视频播放器,而不是纯文本。

要不要切换编辑器?

完全没必要!上面的方案已经是干净且安全的了:前端拦截了非法内容,后端又做了双重过滤,既满足了你的需求,又遵循了Rails的安全规范。如果之后需要扩展允许的标签,只要在sanitizer里添加对应的规则就行。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:13:03