gon对比:一次真实改造复盘

gon对比这件事,不能只看“能不能把后端变量丢给前端”。我用一个 Rails 订单页改造案例讲清楚:gon、data 属性、接口请求、内联 script 各自适合什么场景,哪些看着省事,后面会让你补坑。

步骤一:先看原来的问题

这个案例来自一个 Rails 后台订单详情页。页面上要展示订单金额、优惠券、物流节点,还要给一段前端脚本用这些数据初始化图表。老写法是在 ERB 里拼一段 script,把 Ruby 变量直接塞进 JS。刚开始确实快,十几行就能跑。

问题出在维护阶段。订单备注里出现引号,脚本报错;金额字段有时是 BigDecimal,有时转成字符串,前端判断混乱;页面局部缓存以后,某些变量还拿到旧值。这个时候再做 gon对比,就不是选一个“更潮”的工具,而是看谁能把数据边界说清楚。

步骤二:把四种方案摆到桌面

第一种是内联 script,优点是直接,缺点是转义、安全和可读性都靠人肉把关。第二种是 HTML data 属性,适合少量、跟某个 DOM 节点强绑定的数据,比如 data-order-id、data-status。第三种是前端再调接口,边界最清楚,但页面首屏多一次请求,后台内网页面未必值得。

第四种就是 gon。它的定位很窄:在 Rails controller 或 view 里设置变量,页面渲染时把这些变量安全地挂到 window.gon 上,前端直接读。它不是状态管理,也不是接口替代品,别把它想得太大。

想要完整资源?

会员专享,海量内容

立即查看 →

步骤三:小范围替换验证

我没有一上来全站替换,只挑订单详情页的图表初始化数据。controller 里写 gon.order_chart = { total: ..., paid: ..., refunded: ... },前端入口只读取 gon.order_chart。改完以后最明显的变化是:ERB 里那段难看的 JS 字符串拼接消失了。

这里有个小窍门:gon 里只放“页面初始化必须用”的数据,不放整张订单对象。比如订单有 40 个字段,图表只用 4 个,就只传 4 个。这样前端拿到的数据干净,后端也不容易不小心泄露手机号、地址、内部备注。

步骤四:和 data 属性再比一次

改到一半时,团队有人问:这些数据为什么不用 data 属性?这个问题很关键。我的判断标准是:数据如果服务于某个按钮或组件,用 data 属性;数据如果服务于整个页面初始化,用 gon。比如“取消订单”按钮需要 order_id,用 data-order-id 很合适;图表需要一组统计值,用 gon 更舒服。

这次 gon对比下来,data 属性没有输,它只是边界不同。很多项目乱,是因为把所有后端数据都塞到一个方案里。真正好维护的写法,往往是两三个简单方案各司其职。

步骤五:最终保留的规则

最后我们定了三条规则:少量 DOM 相关数据走 data 属性;页面首屏必须有、且结构稍复杂的数据走 gon;会变化、需要分页、需要权限校验的数据走 API。这样一分,前端和后端都少吵很多。

如果你也在做 gon对比,我建议别从“哪个高级”开始想。先拿一个真实页面,把数据按用途拆开。gon 最适合解决的是 Rails 页面渲染时的初始化数据传递,不适合承担长期交互数据源。认清这个边界,它就很好用。

常见问题

gon 和 data 属性哪个更适合 Rails 项目?
少量、跟具体元素绑定的数据用 data 属性;页面级初始化数据用 gon。比如按钮 ID 用 data,图表配置用 gon。
gon 能完全替代接口吗?
不能。gon 适合页面加载时就确定的数据;用户操作后会变化、需要分页或刷新状态的数据,还是应该用 API。
gon 会不会有安全风险?
风险主要来自你传了不该传的数据。只传前端必需字段,不要把完整模型对象直接塞进去,尤其是用户隐私和后台备注。

获取完整内容

加入会员,海量资源任你看

立即进入 →