Rails 6开启Turbo时DataTables报无效JSON响应错误问题咨询
问题根因
该报错是Turbo与DataTables的生命周期、请求处理逻辑冲突导致的,核心触发点有三个:
- Turbo默认开启页面缓存,跳转页面时会保留上一次页面的DOM状态,再次进入用户列表页时,缓存中残留了之前初始化的DataTables实例,二次调用初始化方法时会复用旧实例的上下文请求数据,后端返回非JSON格式的响应(通常是完整HTML页面),无法被DataTables解析就会抛出Invalid JSON错误。
- 你当前只绑定了
turbo:load事件,但是Turbo触发前进后退、局部渲染时触发的是turbo:render事件,缺失销毁旧实例的逻辑,重复初始化也会导致请求异常。 - 服务端模式下的DataTables发起AJAX请求时,Turbo会默认给请求加上
Accept: text/html的请求头,如果后端没有区分处理XHR请求和普通页面请求,就会返回HTML而不是JSON格式数据。
修复方案
方案1:适配Turbo生命周期,完全保留Turbo功能
- 新增页面缓存前的实例销毁逻辑,避免缓存残留旧实例:
$(document).on('turbo:before-cache', function() { if ($.fn.DataTable.isDataTable('#users_data_table')) { $('#users_data_table').DataTable().destroy(); // 可选:清空表格DOM残留,避免渲染异常 $('#users_data_table').empty(); } });
- 调整初始化事件绑定,覆盖Turbo所有页面加载场景,且初始化前先判断实例是否存在:
$(document).on('turbo:load turbo:render', function() { if (!$.fn.DataTable.isDataTable('#users_data_table')) { $('#users_data_table').DataTable( { // 保留你原有的所有配置不变 columnDefs: [ { targets: 4, className: 'text-center', } ], stateSave: true, "order": [[3, 'desc']], "pagingType": "full_numbers", "dom": '<lf<t>ip>', bProcessing: true // 其余原有配置保持不变 }); } });
- 如果你使用服务端加载数据模式,在DataTables的AJAX配置中明确指定JSON请求头,避免Turbo篡改请求头:
// 原有DataTables配置中新增ajax参数 ajax: { url: '/users', headers: { 'Accept': 'application/json' } }
方案2:低成本局部禁用Turbo
如果不需要在用户列表页使用Turbo功能,可以直接在用户列表页的body标签上添加data-turbo="false"属性,只在该页面禁用Turbo,不影响全站其他页面的Turbo能力,不需要调整JS代码即可解决问题。
内容的提问来源于stack exchange,提问作者Nick_K
相关产品推荐
相关产品推荐

