【问题标题】:uploading a file to Rails JSON API server with Paperclip and Multipart request使用 Paperclip 和 Multipart 请求将文件上传到 Rails JSON API 服务器
【发布时间】:2012-04-15 07:25:41
【问题描述】:

我想将文件从 Android 客户端上传到 Rails JSON API 服务器。

我正在从 Android 客户端发送一个 Multipart/form 请求,如下所示:

Content-Type: multipart/form-data; boundary=d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5
Host: 10.0.2.2:3000
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)

--d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5
Content-Disposition: form-data; name="POSTDATA"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit

{"tags":["test"],"location_id":1,"post":{"content":"test"}}
--d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5
Content-Disposition: form-data; name="IMAGEDATA"; filename="testimage.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary

<BINARY DATA?
--d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5--

在 Rails 控制器中,我正在使用以下代码创建新帖子:

@parsed_json = JSON(params[:POSTDATA])
@post = @current_user.posts.new(@parsed_json["post"]) 

如何让 Paperclip 保存多部分表单中的附件?

我可以这样做:

if params.has_key?(:IMAGEDATA)
    photo = params[:IMAGEDATA]
    photo.rewind

    @filename = "/tmp/tempfile"
    File.open(@filename, "wb") do |file|
      file.write(photo.read)
    end

    @post.photo = File.open(@filename)
  end

但它看起来不是最好的解决方案,而且在多部分请求中传递的文件名也没有使用。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 paperclip


    【解决方案1】:

    执行此操作的纯 json 方法是不传递 content-type multipart-form 并将文件作为 json 中的 base64 编码字符串传递。

    我想通了感谢这篇文章:http://www.rqna.net/qna/xyxun-paperclip-throws-nohandlererror-with-base64-photo.html

    这是一个json的例子:

    "{\"account\":{\"first_name\":\"John\",\"last_name\":\"Smith\",\"email\":\"john@test.com\",\"password\":\"testtest\",\"avatar\":{\"data\":\"INSERT BASE64 ENCODED STRING OF FILE HERE\",\"filename\":\"avatar.jpg\",\"content_type\":\"image/jpg\"}}}"
    

    然后在保存模型之前,在控制器中像这样处理传入的头像。

    def process_avatar
      if params[:account] && params[:account][:avatar]
        data = StringIO.new(Base64.decode64(params[:account][:avatar][:data]))
        data.class.class_eval { attr_accessor :original_filename, :content_type }
        data.original_filename = params[:account][:avatar][:filename]
        data.content_type = params[:account][:avatar][:content_type]
        params[:account][:avatar] = data
      end
    end
    

    【讨论】:

    • 目前为止工作正常。我很好,但是有人可以解释一下这是如何工作的,我们实际上用 StringIO 类填充 params[:account][:avatar] 吗?
    • 这对我来说是一半,如果图片太大,base64 字符串也是如此,那么它会崩溃并引发 Errno::E2BIG 异常。
    • 我认为将这种逻辑更多地添加到模型中更加清晰,如下所述:eggie5.com/54-ios-rails-image-uploads
    【解决方案2】:

    所以,我猜你的 Post 模型看起来像这样:

    class Post < ActiveRecord::Base
      has_attached_file :photo, :styles => { ... }
      ...
    end
    

    所以你应该能够做一些像这样简单的事情:

    @post.photo = params[:IMAGEDATA] if params[:IMAGEDATA].present?
    @post.save if @post.valid?
    

    它应该保存照片。

    如果您需要做一些更复杂的事情,请尝试将表单数据重新排列为 Paperclip 所期望的格式的数据。如果您需要更深入地挖掘,take a look inside Paperclip's Paperclip::Attachment class

    堆栈溢出交叉引用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 1970-01-01
      • 2013-11-26
      相关资源
      最近更新 更多