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

Stimulus控制器Fetch请求406错误及ActionController格式问题排查

解决Stimulus fetch请求406 Not Acceptable及ActionController::UnknownFormat错误

核心问题

你的请求以text/vnd.turbo-stream.html为Accept头,但Rails控制器的edit_description动作未配置支持turbo_stream格式,导致服务器无法返回匹配的内容类型,触发406错误和UnknownFormat异常。


解决方案

1. 让控制器支持turbo_stream格式

在MembersController的edit_description方法中,显式声明支持的响应格式,确保能匹配你的Turbo Stream模板:

def edit_description
  @member = Member.find(params[:id])
  # 明确响应html和turbo_stream两种格式
  respond_to do |format|
    format.html
    format.turbo_stream
  end
end

如果你的Rails版本支持respond_with,也可以简化为:

def edit_description
  @member = Member.find(params[:id])
  respond_with @member
end

只要app/views/members/edit_description_turbo_stream.erb存在,控制器会自动匹配该模板。

2. 调整Stimulus请求的Accept头(按需选择)

如果你的场景不需要Turbo Stream,只是加载HTML模态框,直接将Accept头改为text/html即可:

// edit_description.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  openModal() {
    fetch(this.data.get("url"), {
      headers: {
        "Accept": "text/html", // 替换为HTML格式
        "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
      }
    })
    .then(response => {
      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
      return response.text()
    })
    .then(html => {
      document.getElementById("modal-container").innerHTML = html
      // 这里加模态框显示逻辑,比如触发Bootstrap模态框
    })
    .catch(error => this.handleError(error))
  }

  handleError(error) {
    // 针对性处理错误
    if (error.message.includes("406")) {
      alert("当前请求格式不被服务器支持,请检查配置")
    } else {
      alert("加载失败,请稍后重试")
    }
    console.error("请求错误:", error)
  }
}

3. 确保Turbo配置正确(若使用Turbo Stream)

  • 确认application.html.erb中已引入Turbo:
    <%= turbo_include_tags %> <!-- Rails 7+ 推荐方式 -->
    
  • 若手动导入,确保Stimulus控制器所在的pack文件中已加载Turbo:
    import "@hotwired/turbo-rails"
    

4. 优雅处理错误的双向方案

前端层面

在fetch的错误捕获逻辑中,区分不同状态码,给出友好提示:

handleError(error) {
  let message = "请求出错,请稍后重试"
  if (error.message.includes("406")) {
    message = "服务器无法处理当前请求格式,请刷新页面后重试"
  } else if (error.message.includes("404")) {
    message = "找不到指定资源"
  }
  // 可以用页面内的提示组件替代alert,更优雅
  document.getElementById("error-alert").textContent = message
  document.getElementById("error-alert").classList.remove("hidden")
}

后端层面

在控制器中捕获ActionController::UnknownFormat异常,返回友好响应:

class MembersController < ApplicationController
  rescue_from ActionController::UnknownFormat, with: :handle_unknown_format

  private

  def handle_unknown_format
    respond_to do |format|
      format.html { redirect_to request.referer || members_path, alert: "请求格式错误" }
      format.json { render json: { error: "不支持的请求格式" }, status: :not_acceptable }
    end
  end
end

5. 验证模板路径与内容

确保edit_description_turbo_stream.erb位于app/views/members/目录下,且内容符合Turbo Stream语法:

<%= turbo_stream.update "modal-container" do %>
  <%= render "description_modal", member: @member %>
<% end %>

内容的提问来源于stack exchange,提问作者Yadnyesh-Dashpute

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:46:28