Rails 7渲染VTT字幕时输出HTML实体编码而非原始字符问题
问题根因
Haml默认对所有通过=语法输出的动态内容开启HTML实体转义,即使你指定了:vtt渲染格式,这个默认转义规则也不会自动关闭。你拼接的时间轴字符串里包含>字符,会被自动转义为>,最终输出的-->不符合VTT格式要求。
另外你模板里写的= print "\n"属于冗余代码,Haml渲染时会自动处理换行,调用print反而可能输出多余的空值字符。
可直接落地的修复方案
任选一种即可:
- 方案1:给拼接好的时间轴字符串加
html_safe标记,告诉模板引擎这段内容无需转义,直接原文输出。修改模板对应行为:
= (cue.start_time.strftime("%H:%M:%S.%L") + " --> " + cue.end_time.strftime("%H:%M:%S.%L")).html_safe
这里拼接的内容都是固定时间格式和写死的分隔符,不存在用户提交的恶意内容,使用html_safe没有XSS安全风险。
- 方案2:使用Rails内置的
raw辅助方法输出时间行,自动跳过转义逻辑:
= raw "#{cue.start_time.strftime("%H:%M:%S.%L")} --> #{cue.end_time.strftime("%H:%M:%S.%L")}"
- 方案3:删掉控制器里冗余的
@dash实例变量,直接在模板里用插值语法写固定分隔符,不走动态转义逻辑:
WEBVTT - @cues.each do |cue| = cue.identifier #{cue.start_time.strftime("%H:%M:%S.%L")} --> #{cue.end_time.strftime("%H:%M:%S.%L")} line:90%
这种写法最简洁,也不会触发转义问题,同时可以把VTT要求的line:90%定位参数直接写在时间行末尾,和你预期的输出格式完全匹配。
验证方式
修复后直接访问接口,查看响应原文,确认-->是原始字符而非HTML实体,就能被HTML5的<track>标签正常识别加载。
内容的提问来源于stack exchange,提问作者Patrick Vellia
相关产品推荐
相关产品推荐

