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

Rails 5.x:为sanitize处理的所有链接添加nofollow属性

给Rails的sanitize方法自动添加rel="nofollow"到外部链接

嘿,这个需求其实不用去翻vendor里的diff文件,Rails本身就有很简便的扩展方式,而且完全兼容你现有的sanitize用法,不用改模板代码~

最直接的实现:在Helper里覆盖sanitize方法

Rails的Action View辅助方法允许我们在ApplicationHelper里重写或包装原有的sanitize方法,这样所有模板里的sanitize调用都会自动用上新逻辑。步骤如下:

  1. 打开app/helpers/application_helper.rb,添加以下代码:
module ApplicationHelper
  def sanitize(html, options = {})
    # 先调用原生sanitize完成基础的HTML清理
    sanitized_html = super(html, options)
    
    # 用Nokogiri解析清理后的HTML,处理外部链接
    doc = Nokogiri::HTML.fragment(sanitized_html)
    
    doc.css('a').each do |a_tag|
      href = a_tag['href']
      next unless href.present?

      begin
        uri = URI.parse(href)
        # 判断是否为外部链接:不是相对路径,且host不等于当前站点的host
        if uri.host.present? && uri.host != request.host
          # 合并现有的rel属性和nofollow,去重
          rel_values = (a_tag['rel'] || '').split << 'nofollow'
          a_tag['rel'] = rel_values.uniq.join(' ')
        end
      rescue URI::InvalidURIError
        # 遇到无效URL直接跳过,不处理
        next
      end
    end

    # 返回处理后的HTML
    doc.to_html
  end
end
  1. 保存后重启服务器,所有模板里的sanitize调用就会自动给外部链接加上rel="nofollow"了。

优化小技巧

如果你的站点有子域名或者需要信任某些外部域名,可以修改判断逻辑:

# 定义信任的域名列表
trusted_hosts = [request.host, 'your-trusted-domain.com', 'sub.your-domain.com']

if uri.host.present? && !trusted_hosts.include?(uri.host)
  # 添加nofollow逻辑
end

为什么这个方法最简便?

  • 完全兼容原有功能:先调用原生sanitize完成HTML清理,再额外处理链接,不破坏现有逻辑
  • 不用改模板:所有已有的sanitize调用自动生效,无需逐个修改HAML文件
  • 无需修改框架核心代码:避免了去vendor里找定义或者改配置的麻烦,属于Rails推荐的扩展方式

内容的提问来源于stack exchange,提问作者zwol

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:07:06