1

让我告诉你发生了什么事。

我有一个完全是 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 集成是非常标准的,但在 rails 应用程序本身内部功能齐全,一旦我使用简单的 erb multipart/form-data 并且只是默认的表单提交发送,一切都会完美运行。

如果我发送没有图像参数的数据产品 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: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 应用程序的方法,对此并不完全确定,但我正在努力。

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

4

4 回答 4

1

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

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

于 2013-06-21T15:48:34.497 回答
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
于 2014-07-15T13:16:12.710 回答
0

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

于 2013-05-29T08:39:59.927 回答
0

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

于 2013-06-06T14:23:01.013 回答