Подтвердить что ты не робот

Загрузка файла на сервер API Rails JSON с помощью запроса на перенос и многопользовательский режим

Я хочу загрузить файл с Android-клиента на сервер Rails JSON API.

Я отправляю запрос на Multipart/form от клиента Android, который выглядит следующим образом:

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

но это не похоже на лучшее решение, также не используется имя файла, которое передается в многостраничном запросе.

4b9b3361

Ответ 1

Чистым способом json для этого является не пропускать многостраничную форму типа контента и передавать файл в кодировке base64 в json.

Я понял это благодаря этому сообщению: http://www.rqna.net/qna/xyxun-paperclip-throws-nohandlererror-with-base64-photo.html

Вот пример json:

"{\"account\":{\"first_name\":\"John\",\"last_name\":\"Smith\",\"email\":\"[email protected]\",\"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

Ответ 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. И если вам нужно копать глубже, заглянуть внутрь класса Paperclip Paperclip::Attachment.

Перегрузка