2013-05-26 2 views
1

позвольте мне рассказать вам, что происходит.Красные огни о загрузке изображения Jquery Ajax в Rails paperclip

У меня есть веб-клиент, который полностью html/css/JavaScript (без серверного языка) и сервер Ruby on Rails, который потребляет и получает данные json.

Раньше все шло хорошо, как только я решил, как решить некоторые проблемы с междоменными доменами, но теперь мне нужно включить изображение, и это принесло мне проблемы с отправкой моих данных через обычный JQuery Ajax.

Моя форма основана на Twitter Bootstrap и имеет простые тексты полого ввод файла и кнопка, чтобы загрузить изображение:

<div class="controls"> 
     <input class="input-file" id="fileInput" type="file" value="" required /> 
     <input id="file-upload-btn" type="button" value="upload"/> 
    </div> 

В моем functions.js файл JavaScript Я просто получить форму Params и я Я пытаюсь использовать API FileReader для работы с файлом изображения. Смотрите следующее:

function create_image(file, callback) { 
    var reader = new FileReader(); 
    reader.onload = function() { callback(reader.result) }; 
    reader.readAsDataURL(file); 
} 

Насколько я знаю, метод readAsDataURL() возвращает закодированный base64 материал и там мы идем.

На данный момент я просто выбрать любой файл изображения через этот вход файла, и я начинаю что бы процесс загрузки с помощью JQuery Ajax Материала:

$upload = $("#form-produto-container"); //caches the form dom element 

    $upload.delegate('#file-upload-btn','click',function(e){ //fires the upload 

var file = document.getElementById('fileInput').files[0]; //get the image file 

create_image(file, function(result) { 
     var img = result.replace(/^data:image\/[^;]/, 'data:application/octet-stream'); 

    $(".fileupload-new.thumbnail img").attr('src',img); //display thumbnail 
    }); 
    //.... goes on 'till the reach the ajax which I'll explain later 

«До этого момента, что работает как шарм, как только я просто может получить закодированные данные файла, разделить его метаданные, изменить его и установить в атрибут src моего эскиза img, когда я запускаю кнопку загрузки.

Теперь дело становится серьезным. мне нужно отправить все данные в формате JSON хорошо отформатированный объект на мои рельсы обслуживание остального, и это выглядит следующим образом:

$submmit.on("click",function(e){ // fires ajax sending the whole data 
    e.preventDefault(); 

    //...here I get all data into form fileds using JQuery selectors and set it into vars 
    //considering that I already got the params I can set my json object like following 
    // REMEMBER:the img var contains the image data previously added through FileReader 

    dataproduct = { "product":{"name": name, "price" : price, "description":desc, "place" : place, "tag_list" : array_tags, "category_ids" : category_ids, "image" : img }}; 

    $.ajax({ 
    type: 'post', 
    url: rootUrl+'/ajax_products.json', 
    data: dataproduct, 
     success: function(data){ 
      $msg.addClass("alert alert-success"); 
    $msg.html("Your product was succsessfuly added !!!"); 
    }, 
    error: function(jqxhr){ 
     console.log(jqxhr); 
     }, 
}); //ajax end 
}); // submmit end 

Как вы могли видеть, что это довольно стандартный Аякса не посылая, ничего умереть.

В моей Rails стороне у меня есть: Модель:

class Product < ActiveRecord::Base 
attr_accessible :name, :price, :category_ids, :tag_list, 
:place, :description, :image 
has_and_belongs_to_many :categories 
acts_as_taggable 
validates :name, :price, :category_ids, :tag_list, 
:place, :description, :presence => true 

has_attached_file :image, styles: { 
thumb: '100x100>', 
square: '200x200#', 
medium: '300x300>' 
}, 
:storage => :s3, 
:s3_credentials => "#{Rails.root}/config/s3.yml", 
:path => ":attachment/:id/:style.:extension", 
:bucket => 'serverassets' 

require 'tempfile' 

def set_picture(data) 

file = Tempfile.new(['test', '.jpg']) 

begin 
    file.binmode 
    file.write(data) 
    self.image = file 
ensure 
    file.close 
    file.unlink 
end 
end 

конец

Метод set_picture получает данные, которые якобы сырым файл изображения. Создает временный файл и записывает в него содержимое данных и устанавливает int в self.image.

Теперь контроллер:

def ajax_product 
    @product = Product.new 
    uploaded_file = @product.set_picture(params[:product][:image]) 
    params[:product][:image] = uploaded_file 
    @product.attributes = params[:product] 

respond_to do |format| 
    if @product.save 
    format.json { render json: @product, status: :created, location: @product } 
    else 
    format.json { render json: @product.errors, status: :unprocessable_entity } 
    end 
end 

конца

В этом контроллере я просто поймать файл данные, связанные с входящим запросом и обработать его метод корыта set_picture модели в uploaded_file локальных переменное. Наконец, я повторно устанавливаю исходное значение хеша params [: product] [: image].

Параметры скрепки и интеграция с азатонами S3 довольно стандартны, но полностью функциональны. Внутри самого приложения rails все отлично работает, как только я использую простые эрбированные мультиформатные данные и данные формы, а также отправку отправки по умолчанию.

Если я отправил dataproduct json без параметра изображения, все работает отлично. Но когда он идет с параметром img, я получил эти ошибки в моей консоли !!!

Command :: identify -format '%wx%h,%[exif:orientation]' '/tmp/test20130609-4953-  aqzvpm20130609-4953-12ijmo6.jpg[0]' 
[paperclip] An error was received while processing:  #<Paperclip::Errors::NotIdentifiedByImageMagickError:  Paperclip::Errors::NotIdentifiedByImageMagickError> 

Я читал много вопросов о кокаине и определить и это все работает на itselves, кстати, если я бегу Paperclip.run («определить», «-format«% WX% ч, % [exif: orientation] ': file ",: file =>"/tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg [0 ").

Я получаю: идентификатор: не файл JPEG: начинается с 0x30 0x30 '/ tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg [0' @ error/jpeg.c/EmitMessage/236.

Поэтому я считаю, что это должен быть способ «восстановить» исходный файл jpg-кодировки в приложении rails, но не совсем уверен в этом, но я над этим работаю.

Wow guys, извините за это, я пробовал много вещей, таких как добавление различных параметров contentType и processData ajax, а также другие методы FileReader, такие как readAsArrayBuffer() и readAsText(), отправка файла без расщепления метаданные и методы для различной кодировки символов, utf-8, ascII, base64 и так далее и дальше ... ничего из этого не сработало, но я действительно устал, и я очень признателен за помощь xx

ответ

0

На самом деле я получил это давным-давно, но сейчас я поставлю фрагмент, который решил его на основе кончиков jyurek.

require 'tempfile' 

def set_picture(data) 

    file = Tempfile.new(['test', '.jpg']) 

    begin 
     file.binmode 
     file.write(ActiveSupport::Base64.decode64(data)) #did the trick 
     self.image = file 
    ensure 
     file.close 
     file.unlink 
    end 
end 
0

Невозможно стоит настоящая проблема. Похоже, вы хотите отправить данные файла, используя плагин загрузки файла ajax. Загрузка файла Ajax отправляет нессертифицированные данные, отправляя скрытый i-кадр. Попробуйте один раз с загрузкой файла ajax и обычной отправкой формы и проверьте в консоли фактическую ошибку.

+0

Спасибо за советы @Sabyasachi Ghosh! Но на самом деле я не использую плагины, я просто использую API FileReader для получения необработанных данных файла или аналогичного, назначил его в json-объект и отправил его в мой веб-сервис restor, основанный на RoR. Я думаю, что регулярная форма может работать, но мой webclient - полный ajax, и я просто верю, что это возможно, я просто борюсь за то, как это сделать. Я думаю, что есть способ установить правильную кодировку файла, и поэтому сэкономленные на ней рельсы paperclip. – marleyferreira

0

Я вижу в вашей трассе стека вы используете meta_request. У нас была аналогичная проблема с этим gem и загрузкой jQuery. Попробуйте заставить его работать без meta_request. Тогда вы можете захотеть посмотреть исправление мета запроса или открыть билет здесь https://github.com/dejan/rails_panel/issues.

+0

Спасибо за подсказку @t_itchy! Я проверю это прямо сейчас. – marleyferreira

+0

Только что сорвал meta_request, но он не изменил мой выход журнала значительно. То, что я застрял, - это то, как захватить необработанные данные из обычного файла изображения (jpg, png ..), отправить его на мой сервер, установить его самостоятельно.изображение и сохранить его. Когда я запускаю Paperclip.run («идентифицировать», «-формат»% wx% h,% [exif: orientation] ': file ",: file =>" tmp/temp_file20130906-2165-1t7m9i920130609-2165-1wb3pv7.jpg [ 0] ") Журналы консоли, что мой файл не является файлом jpg !!! Хорошо, это похоже на подсказку, но я ищу, как преобразовать содержимое изображения, отправленное моим запросом ajax, в действительный файл jpg. – marleyferreira

1

Один, команда, которую вы используете для проверки convert, отсутствует. Вы вставили "/tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg[0", который не имеет конца ], поэтому я не ожидал, что это сработало.

Два, я хотел бы спросить, если это работает, если добавить, что ], но я знаю, что это не будет: Вы сказали, что Base64 кодирует его на стороне JS с FileReader, но вы никогда не говорите, что вы Base64 расшифровывает Это. В вашем методе set_picture вы должны декодировать данные. Это будет ближе, чтобы получить то, что вам нужно. Вы также можете просмотреть файл, а не просто отправить его через convert, чтобы убедиться, что он пережил поездку по серверу.

+0

Довольно приятно @jyurek! На самом деле есть дополнительный «]», заканчивающийся в моем коде, я просто испортил его неправильной копией/вставкой здесь. Да, я читал о Base64decoding, но я немного смутился, как только буфер базы Base64encoded действительно выглядит как обычный jpg-файл после его открытия в текстовом редакторе. На самом деле я подумал о том, чтобы отправить на Base сервер уже без оснований Base64Decoding, поэтому мне даже не нужно было расшифровывать его на стороне сервера, но я не уверен, действительно ли он эффективен. Я попробую сделать это на стороне сервера, как вы сказали. С уважением, человек! – marleyferreira