【问题标题】:Get filename in Rails backend from file upload in React frontend从 React 前端的文件上传中获取 Rails 后端的文件名
【发布时间】:2017-04-06 23:05:44
【问题描述】:

我在 React 中有一个文件上传组件,它向我的 Rails API 发出 POST:

class uploadFormState {
  @observable file;

  constructor() {
     this.file = '';
  }

  @action.bound setFile(file){
   this.file = file[0];
   this.fileName = file[0].name;
  }

  @action.bound uploadFile() {
    $.ajax({
        url: AppConstants.APIEndpoints.USERLOCATIONS + '/1/photos/1/upload',
        headers: { "Authorization": localStorage.getItem('authToken') },
        data: this.file,
        processData: false,
        contentType: false,
        type: 'POST',
        success: function (data) {
            alert(this.data.name + " uploaded successfully!");
        }
     });
   }
}

export default new uploadFormState();

正如您在数据字段中看到的,我正在尝试将原始文件名传递给 rails 后端。问题是,我不知道如何获取这些数据参数。

我的上传方法是这样的:

  def upload
    @photo.upload_model(request.body)
  end

类方法`upload_model'看起来像这样:

  def upload_model(model_file)
    model = StorageBucket.files.new(
    key: "models/#{id}",
    body: model_file.read,
    public: true
    )

    model.save

    update_columns model_url: model.public_url
  end

我尝试将 ajax 调用中的 data 字段更改为 data: {file: this.file, fileName: this.file.name},但我不确定如何从 rails 端访问这两个参数。如果我以这种方式更改数据参数,它会导致上传object Object 的文本。 request.bodyStringIO ruby​​ 类型。当数据字段为this.file(即,它将文件上传到谷歌存储)时,该方法本身有效,但是,文件名丢失了扩展名,这并不理想。

所以总结一下,我如何在 Rails 后端访问上传的文件名?

【问题讨论】:

  • 文件上传成功了吗?您能否添加正在调用的上传操作的日志?
  • 是的,以上代码成功上传模型
  • action的日志怎么样?
  • 我能够在下面的答案的帮助下解决它。

标签: ruby-on-rails ruby ajax reactjs


【解决方案1】:

您是否尝试过使用FormData?在您的情况下,它将是:

JS:

// Use FormData to build params 

let form = new FormData();
form.append("file_name", file[0].name);

// Send form as part of ajax post

$.ajax({
  ...
  data: form,
  ...
})

然后在 Rails 端,你可以通过params[:file_name] 获得file_name(在控制器中)

这是一个快速的建议,希望对您有所帮助。

干杯

【讨论】:

    【解决方案2】:

    非常感谢@kasperite 建议使用 FormData,这是这个答案的重要组成部分。我将 ajax 调用更改为如下所示:

    @action.bound uploadFile() {
      let form = new FormData();
      form.append("file", this.file);
      $.ajax({
        url: AppConstants.APIEndpoints.USERLOCATIONS + '/1/photos/1/upload',
        headers: { "Authorization": localStorage.getItem('authToken') },
        data: form,
        processData: false,
        contentType: false,
        type: 'POST',
        success: function (data) {
          alert(this.data.name + " uploaded successfully!");
        }
      });
    }
    

    然后将我的控制器更改为如下所示:

    def upload
      @photo.upload_model(params[:file].original_filename, params[:file].tempfile)
    end
    

    params[:file].original_filename 是文件名,params[:file].tempfile 是实际文件。

    我的类方法现在看起来像这样:

    def upload_model(original_filename, model_file)
      model = StorageBucket.files.new(
      key: "models/#{id}-#{original_filename}",
      body: model_file.read,
      public: true
      )
    
      model.save
    
      update_columns model_url: model.public_url
    end
    

    【讨论】:

      猜你喜欢
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多