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

如何将POST请求的FormData传递至Rails控制器并存储JSON数据

没问题,我来帮你搞定这个FormData传递到Rails控制器的问题,分两种常见场景给你讲解,你可以按需选择:

方式一:使用FormData传递(适合需同时上传文件的场景)

前端代码完善

你之前的FormData构造没写完,按照Rails的参数命名规范,得用模型名[字段名]的格式来append参数,这样控制器才能自动识别。完整的JS代码如下:

function save() {
  var tojs = myDiagram.model.toJSON();
  var jsonStr = JSON.stringify(tojs);
  var formData = new FormData();
  // 关键:遵循Rails参数命名规则
  formData.append('tournoi[payload]', jsonStr);

  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/tournois', true);
  
  // 重要提示:不要手动设置Content-Type,FormData会自动生成正确的multipart/form-data请求头
  xhr.onload = function() {
    if (xhr.status >= 200 && xhr.status < 400) {
      console.log('数据保存成功!');
    } else {
      console.error('保存失败,状态码:', xhr.status);
    }
  };
  
  xhr.send(formData);
}

Rails控制器处理

因为前端传的是JSON字符串,我们需要把它解析成Ruby Hash再存入数据库(这样后续操作payload里的字段会更方便)。在你的TournoisController里这样写:

class TournoisController < ApplicationController
  def create
    @tournoi = Tournoi.new(tournoi_params)
    if @tournoi.save
      render json: @tournoi, status: :created
    else
      render json: @tournoi.errors, status: :unprocessable_entity
    end
  end

  private

  def tournoi_params
    // 先白名单参数,再把JSON字符串转成Hash
    params.require(:tournoi).permit(:payload).tap do |whitelisted|
      if params[:tournoi][:payload].present?
        whitelisted[:payload] = JSON.parse(params[:tournoi][:payload])
      end
    end
  end
end

方式二:直接发送JSON请求(纯数据场景推荐)

如果不需要上传文件,直接发JSON格式的请求会更简洁,Rails也能自动解析请求体:

前端代码

function save() {
  var tojs = myDiagram.model.toJSON();
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/tournois', true);
  
  // 设置请求头为JSON格式
  xhr.setRequestHeader('Content-Type', 'application/json');
  
  xhr.onload = function() {
    if (xhr.status >= 200 && xhr.status < 400) {
      console.log('数据保存成功!');
    } else {
      console.error('保存失败,状态码:', xhr.status);
    }
  };
  
  // 直接发送嵌套模型参数的JSON字符串
  xhr.send(JSON.stringify({
    tournoi: {
      payload: tojs
    }
  }));
}

Rails控制器处理

这种情况下,Rails会自动把JSON请求体解析成参数Hash,控制器的参数处理会更简单:

class TournoisController < ApplicationController
  def create
    @tournoi = Tournoi.new(tournoi_params)
    if @tournoi.save
      render json: @tournoi, status: :created
    else
      render json: @tournoi.errors, status: :unprocessable_entity
    end
  end

  private

  def tournoi_params
    params.require(:tournoi).permit(:payload)
  end
end

额外注意点

  • 你的迁移文件是正确的,t.json 'payload'会在PostgreSQL中创建json类型字段,Rails会自动处理Hash和JSON字符串的存储。
  • 如果你需要对payload内的字段做查询(比如Tournoi.where("payload->>'key' = ?", 'value')),只要确保存入的是合法JSON格式即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:10:36