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

Rails 6:使用fetch()和params渲染.js.erb时HTML未替换问题

解决Rails中fetch()调用.js.erb模板不更新页面的问题

问题背景

升级旧Rails应用时,将原jQuery的$.ajax()替换为fetch()调用后,服务器能正常处理请求并返回渲染好的.js.erb代码,浏览器控制台也能接收到内容,但页面中#workbar_switch的内容始终未被指定局部视图替换。

现有代码

控制器代码

def switch_state
  permitted_params = params.permit(:partial)
  @partial = permitted_params[:partial].to_s
  @exercise = current_exercise  # defined somewhere else
  respond_to do |format|
     format.js
  end
end

switch_state.js.erb代码

$('#workbar_switch').html("<%= j render(partial: @partial, :locals => {exercise: @exercise@}) %>");

fetch调用代码

function switchState(partial, exercise){
  const params = new URLSearchParams();
  params.append('partial', partial);

  fetch("/work/switch_state", {
    method: 'POST',
    headers: {
        'Accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',
        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: params
  })
  .then(response =>  {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.text()
  })  
  .then(responseText => {
    console.log("received js", responseText)
  })
  .catch(error => {
    console.log('Update failed', error)
    console.log('error', error.message)
  })
  .finally(() => {
  })
}

解决建议

  • 手动执行返回的JS代码
    fetch() API不会自动执行返回的JavaScript内容,必须手动处理。可以在获取到responseText后执行以下操作:

    .then(responseText => {
      console.log("received js", responseText);
      // 方式1:直接执行(注意安全风险)
      eval(responseText);
      // 方式2:创建script标签插入页面(更安全)
      const script = document.createElement('script');
      script.textContent = responseText;
      document.body.appendChild(script);
      document.body.removeChild(script);
    })
    

    注意:使用eval()时要确保返回的JS代码来自可信源,避免XSS攻击。

  • 修复js.erb中的语法错误
    现有switch_state.js.erb里存在笔误:exercise: @exercise@多了一个@符号,会导致生成的JS代码无效。修正后代码:

    $('#workbar_switch').html("<%= j render(partial: @partial, locals: {exercise: @exercise}) %>");
    
  • 确认jQuery是否正常加载
    返回的JS代码依赖$(jQuery),如果页面已移除jQuery,这段代码会执行失败。可以在浏览器控制台输入$验证是否存在:

    • 若jQuery仍在页面中,确保加载顺序正确;
    • 若已移除jQuery,将JS代码改为原生DOM操作:
      document.getElementById('workbar_switch').innerHTML = "<%= j render(partial: @partial, locals: {exercise: @exercise}) %>";
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:04:55