Rails 5.x:为sanitize处理的所有链接添加nofollow属性
给Rails的sanitize方法自动添加rel="nofollow"到外部链接
嘿,这个需求其实不用去翻vendor里的diff文件,Rails本身就有很简便的扩展方式,而且完全兼容你现有的sanitize用法,不用改模板代码~
最直接的实现:在Helper里覆盖sanitize方法
Rails的Action View辅助方法允许我们在ApplicationHelper里重写或包装原有的sanitize方法,这样所有模板里的sanitize调用都会自动用上新逻辑。步骤如下:
- 打开
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
- 保存后重启服务器,所有模板里的
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
相关产品推荐
相关产品推荐

