【问题标题】:Red lights about Jquery Ajax image uploading to Rails paperclip关于将 Jquery Ajax 图像上传到 Rails 回形针的红灯
【发布时间】:2013-05-26 01:07:29
【问题描述】:

让我告诉你发生了什么。

我有一个完全是 html/css/JavaScript(无服务器端语言)的 Web 客户端,以及一个使用和接收 json 数据的 Ruby on Rails 服务器。

早期一切都很好,一旦我知道如何解决一些跨域问题,但现在我需要包含一个图像,这给我带来了通过常规 J​​Query 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 文件中,我只获得了表单参数,我正在尝试使用FileReader API 来处理图像文件。 请参阅以下内容:

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

据我所知,readAsDataURL() 方法返回一个编码的 base64 内容,然后就可以了。

现在我只需通过该文件输入选择任何图像文件,然后通过 JQuery Ajax Stuff 开始上传过程:

$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

'到那时为止,一旦我触发了上传按钮,我就可以获取编码的文件数据,拆分它的元数据,更改它并将其设置到我的缩略图 img 标签的 src 属性中,这件事就像一个魅力。

现在事情变得严重了。 我需要将所有数据发送到格式正确的 json 对象到我的 rails rest 服务,它是这样的:

$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

正如您所见,它是非常标准的 ajax 发送,没什么好死的。

在我的 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 模型的方法将其处理到 upload_file 局部变量中。最后我重新设置了 params[:product][:image] 原始哈希值。

Paperclip 设置和 S3 amazon 集成非常标准,但功能齐全 一旦我使用一个简单的 erb multipart/form-data 并且只是默认的表单提交发送,在 rails 应用程序本身内一切都会完美运行。

如果我发送没有图像参数的数据产品 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>

我一直在阅读很多关于可卡因和识别的问题,如果我运行 Paperclip.run("identify", "-format '%wx%h,%[exif:方向]' :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 应用程序的方法,对此并不完全确定,但我正在努力。

哇,伙计们,抱歉这么久,我一直在尝试很多事情,例如添加不同的 contentType 和 processData ajax 设置,还有其他 FileReader 方法,如 readAsArrayBuffer() 和 readAsText(),发送没有拆分元数据的文件以及不同字符编码的方法,utf-8,ascII,base64 等等……这些都不起作用,但我真的很累,我真的很感谢一些帮助 x.x

【问题讨论】:

    标签: ruby-on-rails ajax image paperclip filereader


    【解决方案1】:

    第一,您正在运行以测试convert 的命令缺少字符。你粘贴了"/tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg[0",它没有结尾],所以我不认为它会起作用。

    二,如果你添加],我会问它是否有效,但我知道它不会:你说你用FileReader在JS端对它进行Base64编码,但你从来没有说过你是Base64 解码它。在您的 set_picture 方法中,您应该解码数据。这将更接近你所需要的。您还可以查看该文件,而不仅仅是通过convert 发送它,以确保它在通过服务器的过程中幸存下来。

    【讨论】:

    • 相当不错@jyurek!实际上我的代码中有一个额外的“]”结尾,我只是在这里通过错误的复制/粘贴弄乱了它。是的,我确实阅读了有关 Base64decoding 的信息,但是一旦您在文本编辑器中打开 Base64 编码的字符串缓冲区,它看起来真的像一个普通的 jpg 文件,我就有点困惑了。实际上,我想过将已经 Base64Decoding 的东西发送到我的服务器,所以我什至不需要在服务器端对其进行解码,但我不确定它是否真的有效。如您所说,我将尝试在服务器端进行操作。最好的问候!
    【解决方案2】:

    无法理解实际问题。似乎您想使用 ajax 文件上传插件发送文件数据。 Ajax 文件文件上传使用提交隐藏的 i-frame 来发送未序列化的数据。请在没有ajax文件上传和正常表单提交的情况下尝试一次,并在控制台中检查实际错误。

    【讨论】:

    • 感谢@Sabyasachi Ghosh 的提示!但实际上我没有使用插件,我只是使用 FileReader API 来获取文件原始数据或类似数据,将其设置为 json 对象并将其发送到基于 RoR 的我的 rest web 服务。我认为常规表单提交可以工作,但我的网络客户端是完整的 ajax,我只是相信它是可能的,我只是在为如何做到这一点而苦苦挣扎。我认为有一种方法可以设置正确的文件编码,因此 rails 回形针可以使用它。
    【解决方案3】:

    我在您的堆栈跟踪中看到您正在使用 meta_request。我们在这个 gem 和 jQuery 上传时遇到了类似的问题。尝试让它在没有 meta_request 的情况下工作。然后您可能想查看修复元请求或在此处打开票证https://github.com/dejan/rails_panel/issues

    【讨论】:

    • 刚刚扯掉了 meta_request 但它并没有显着改变我的日志输出。我遇到的问题是如何从常规图像文件(jpg,png..)中获取原始数据,将其发送到我的服务器,将其设置在 self.image 附件上并保存。当我运行 Paperclip.run("identify", "-format '%wx%h,%[exif:orientation]' :file", :file => "tmp/temp_file20130906-2165-1t7m9i920130609-2165-1wb3pv7.jpg[ 0]") 控制台记录我的文件不是 jpg 文件!!!好的,这似乎是一个线索,但我正在寻找如何将我的 ajax 请求发送的图像内容转换为有效的 jpg 内容。
    【解决方案4】:

    其实我很久以前就搞定了,不过刚才我把根据jyurek技巧解决的sn-p放上去。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-25
      • 2016-03-31
      • 2017-05-16
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      相关资源
      最近更新 更多