【问题标题】:jquery fileupload rails s3 shrine image upload errorjquery fileupload rails s3神社图片上传错误
【发布时间】:2017-11-08 02:04:15
【问题描述】:

我对 Rails 有点陌生,我正在尝试使用 Shrine 将图像直接上传到 S3。我直接上传到 S3 以完美工作,但是,当我引入 jquery 文件上传并上传图像时,chrome 控制台抛出 this error 对我。我不确定我做错了什么,我似乎无法在网上的任何地方找到解决方案。我知道这是一个预兆错误,可能找不到缓存链接,但我不知道如何解决。

编辑:通过在 Routes 文件中包含 presign 代码并将 uploads.js 中的存储位置更改为正确位置来解决此问题。但是,现在我遇到了文件在尝试上传时被回滚的问题。

我正在使用基于云的 ide C9,

这是我的 uploads.js 文件:

$(document).on("turbolinks:load", function(){
$("[type=file]").fileupload({
  add: function(e, data) {
      console.log("add", data);
      data.progressBar = $('<div class="progress"><div class="determinate" 
style="width: 70%"></div></div>').insertBefore("form")
      var options = {
          extension: data.files[0].name.match(/(\.\w+)?$/)[0], //set the 
file extention
         _: Date.now() //prevent caching
      };

      $.getJSON("/autos/upload/cache/presign", options, function(result) {
          console.log("presign", result);
          data.formData = result['fields'];
          data.url = result['url'];
          data.paramName = "file";
          data.submit()
      });

  },
  progress: function(e, data) {
  console.log("progress", data);
  var progress = parseInt(data.loaded / data.total * 100, 10);
  var percentage = progress.toString() + '%'
  data.progressBar.find(".progress-bar").css("width", 
percentage).html(percentage);
  },
  done: function(e, data) {
  console.log("done", data);
  data.progressBar.remove();


  var image = {
    id:       data.formData.key.match(/cache\/(.+)/)[1], // we have to 
remove the prefix part
    storage:  'cache',
    metadata: {
      size:      data.files[0].size,
      filename:  data.files[0].name.match(/[^\/\\]+$/)[0], // IE return full 
path
      mime_type: data.files[0].type
    }
  }
  form = $(this).closest("form");
  form_data = new FormData(form[0]);
  form_data.append($(this).attr("name"), JSON.stringify(image))

  $.ajax(form.attr("action"), {
    contentType: false,
    processData: false,
    data: form_data,
    method: form.attr("method"),
    dataType: "json"
    }).done(function(data) {
        console.log("done from rails", data);
        });
  }
  }); 
});

我的 routes.rb 文件包括:

mount ImageUploader::UploadEndpoint => "/images/upload"

mount Shrine.presign_endpoint(:cache) => "/autos/upload/cache/presign"

我有一个模型,它接受这些图像以及称为 Autos 的其他字段,这包含在 Autos 文件中:

include ImageUploader[:image]

我的汽车控制器是:

class AutosController < ApplicationController
  before_action :find_auto, only: [:show, :edit, :update, :destroy]
  def index
    @autos = Auto.all.order("created_at DESC")
  end

  def show
  end

  def new
    @auto = current_user.autos.build
  end

  def create
    @auto = current_user.autos.build(auto_params[:auto])

    if @auto.save
      flash[:notice] = "Successfully created post."
      redirect_to autos_path
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @auto.update(auto_params[:auto])
      flash[:notice] = "Successfully updated post."
      redirect_to auto_path(@auto)
    else
      render 'edit'
    end
  end

  def destroy
    @auto.destroy
    redirect_to autos_path
  end

  private 

  def auto_params
    params.require(:auto).permit(:title, :price, :description, :contact, :image, :remove_image)
  end

  def find_auto
    @auto = Auto.find(params[:id])     
  end
end

【问题讨论】:

  • 您是否阅读了shrinerb.com/rdoc/files/doc/direct_s3_md.html 以及您使用的说明?
  • @FabrizioBertoglio 我确实读过它,但我在手动构建上传文件的 Shrine 的 JSON 表示时迷失了方向,而且预兆区域似乎无法完全工作。我正在关注 GoRails 直接上传到 S3 教程。

标签: ruby-on-rails c9.io jquery-fileupload-rails shrine


【解决方案1】:

假设您的 image_uploader.rb 定义了 ImageUploader 类,并且假设您的 presign 端点类似于 /autos/upload/cache/presign,那么您的 routes.rb 应该具有如下定义的 presign 路由:

mount ImageUploader.presign_endpoint(:cache) => '/autos/upload/cache/presign'

我希望路由文件中的这个单一更改能让您获得应该包含 3 个键的 presign 对象:urlfieldsheaders

# GET /autos/upload/cache/presign
{
  "url": "https://my-bucket.s3-eu-west-1.amazonaws.com",
  "fields": {
    "key": "cache/b7d575850ba61b44c8a9ff889dfdb14d88cdc25f8dd121004c8",
    "policy": "eyJleHBpcmF0aW9uIjoiMjAxNS0QwMToxMToyOVoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJzaHJpbmUtdGVzdGluZyJ9LHsia2V5IjoiYjdkNTc1ODUwYmE2MWI0NGU3Y2M4YTliZmY4OGU5ZGZkYjE2NTQ0ZDk4OGNkYzI1ZjhkZDEyMTAwNGM4In0seyJ4LWFtei1jcmVkZW50aWFsIjoiQUtJQUlKRjU1VE1aWlk0NVVUNlEvMjAxNTEwMjQvZXUtd2VzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LHsieC1hbXotYWxnb3JpdGhtIjoiQVdTNC1ITUFDLVNIQTI1NiJ9LHsieC1hbXotZGF0ZSI6IjIwMTUxMDI0VDAwMTEyOVoifV19",
    "x-amz-credential": "AKIAIJF55TMZYT6Q/20151024/eu-west-1/s3/aws4_request",
    "x-amz-algorithm": "AWS4-HMAC-SHA256",
    "x-amz-date": "20151024T001129Z",
    "x-amz-signature": "c1eb634f83f96b69bd675f535b3ff15ae184b102fcba51e4db5f4959b4ae26f4"
  },
  "headers": {}
}

上传开始时,您现在将在开发者控制台中找到此对象,而不是之前的 404 not found 错误。


更新

我认为您非常接近解决方案。在您的 create/update 操作中,使用 auto_params[:auto] 而不是 auto_params

您还想查看Association Basics for collection methods 上的 RoR 指南

【讨论】:

  • 感谢您的建议,但它似乎不起作用。我仍然收到 404 错误。我已将其更改为仅挂载 ImageUploader.presign_endpoint(:cache) => '/presign' ,但这不起作用。您所说的一切都已到位,但仍然返回该错误
  • 在您的uploads.js 中,如果您使用$.getJSON("/autos/upload/cache/presign", options, function(result) {},那么您必须定义将请求引导至/autos/upload/cache/presign 的路由;不仅仅是/presign。我希望你能正确理解这个逻辑。现在可能还有其他问题导致 404。您能否建议我们以交互方式解决问题的其他方法?
  • 嘿,谢谢 agian,在阅读您的解决方案之前,我设法解决了缓存问题,这正是您所说的,我的 routes.rb 签名位置有错误。我现在有另一个问题。我在 uploads.js 文件中添加了一段代码,该文件现在在图片上传到一半时回滚。至于其他的沟通方式你们有不和吗?
  • 能否请您更新uploads.js,以便我查看可能导致新问题的新sn-p?
  • 在最后提交ajax的时候,能在rails server log中看到提交的表单数据吗?
【解决方案2】:

我认为您遵循 gorails 直接上传 s3 的教程 在你的 gem 文件中确保你使用正确的 roda 版本 gem 'roda', "~> 2.29.0"

【讨论】:

    猜你喜欢
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 2012-09-23
    • 2011-12-21
    • 1970-01-01
    • 2012-09-11
    相关资源
    最近更新 更多