何が起こっているのか教えてください。
完全に html/css/JavaScript (サーバー側言語なし) である Web クライアントと、json データを消費および受信する Ruby on Rails サーバーがあります。
いくつかのクロスドメインの問題を解決する方法を理解すると、初期はすべてうまくいきましたが、今では画像を含める必要があり、通常の JQuery Ajax を介してデータを送信する際に問題が発生しました。
私のフォームは twitter ブートストラップに基づいており、単純なテキスト フィールド、ファイル入力、および画像をアップロードするためのボタンがあります。
<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 スタッフによるアップロード プロセスを開始します。
$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 モデルのメソッドを介して Uploaded_file ローカル変数に処理します。最後に、params[:product][:image] 元のハッシュ値を再設定します。
ペーパークリップの設定と S3 アマゾンの統合は非常に標準的ですが、単純な erb multipart/form-data とデフォルトのフォーム送信送信のみを使用すると、Rails アプリ自体の内部で完全に機能します。
image パラメータなしで 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>
私はコカインと識別に関する多くの問題を読んできましたが、Paperclip.run("identify", "-format '%wx%h,%[exif:orientation]' を実行すると、これは自動的に機能します。 :file"、:file => "/tmp/test20130609-4953-aqzvpm20130609-4953-12ijmo6.jpg[0")。
私は得る:
だから、元の有効なjpgエンコーディングファイルをレールアプリケーションに「再構築」する方法に違いないと思いますが、それについては完全にはわかりませんが、取り組んでいます。
長い間申し訳ありませんが、さまざまな contentType および processData ajax 設定を追加したり、readAsArrayBuffer() や readAsText() などの他の FileReader メソッドを追加したり、分割されたメタデータやメソッドなしでファイルをさまざまな文字エンコーディング、utf-8、ascII、base64 など...どれも機能しませんでしたが、本当に疲れていて、助けていただければ幸いです xx