让我告诉你发生了什么事。
我有一个完全是 html/css/JavaScript(无服务器端语言)的 Web 客户端,以及一个使用和接收 json 数据的 Ruby on Rails 服务器。
早期一切都很好,一旦我知道如何解决一些跨域问题,但现在我需要包含一个图像,这给我带来了通过常规 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文件中,我只得到了表单参数,我正在尝试使用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