1

何が起こっているのか教えてください。

完全に 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

4

4 に答える 4

1

1 つは、テストするために実行しているコマンドにconvert文字がありません。"/tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg[0"エンディングのないものを貼り付けた]ので、うまくいくとは思いません。

2つ目は、それを追加しても機能するかどうかを尋ねますが、機能し]ないことはわかっています.JS側でBase64でエンコードすると言いましたが、Base64でデコードするFileReaderとは決して言いません. メソッドでは、データをデコードする必要があります。それはあなたが必要とするものを手に入れることに近づくでしょう. ファイルを送信するだけでなく、ファイルを調べて、サーバーを通過した後も残っていることを確認することもできます。set_pictureconvert

于 2013-06-21T15:48:34.497 に答える
0

スタック トレースで、meta_request を使用していることがわかります。この gem と jQuery のアップロードでも同様の問題がありました。meta_request なしで機能するようにしてください。次に、メタリクエストを修正するか、 https://github.com/dejan/rails_panel/issuesでチケットを開くことを検討してください。

于 2013-06-06T14:23:01.013 に答える
0

実はかなり前に入手したのですが、ジュレックのヒントをもとに解決したスニペットを載せておきます。

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 フレームを送信してシリアル化されていないデータを送信します。ajax ファイルのアップロードと通常のフォームの送信を行わずに一度試して、実際のエラーをコンソールで確認してください。

于 2013-05-29T08:39:59.927 に答える