2013-05-26 1 views
1

무슨 일이 일어나는지 알려주도록하겠습니다.Rails 클립 클립에 Jquery Ajax 이미지 업로드시 빨간색 표시 등

전적으로 html/css/JavaScript (서버 측 언어 없음) 인 웹 클라이언트와 json 데이터를 사용하고 수신하는 Ruby on Rails 서버가 있습니다.

초기에는 모든 문제가 해결되었지만 일부 크로스 도메인 문제를 해결할 방법을 찾았지만 지금은 이미지를 포함해야하므로 일반 JQuery Ajax를 통해 데이터를 전송하는 데 문제가 발생했습니다.

내 양식 트위터 부트 스트랩을 기반으로 간단한 텍스트 필드가됩니다

, 파일 입력과 버튼 이미지 업로드 : 난 그냥 양식 PARAMS을 얻을 자바 스크립트 파일 내 functions.js에서

<div class="controls"> 
     <input class="input-file" id="fileInput" type="file" value="" required /> 
     <input id="file-upload-btn" type="button" value="upload"/> 
    </div> 

및 I FileReader API를 사용하여 이미지 파일을 처리하려고합니다.

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

는 지금까지 내가 알고있는 readAsDataURL() 메소드는 base64로 인코딩 된 물건을 반환하고 거기에 우리가 간다 : 다음을 참조하십시오.

지금은 그냥 그 파일 입력을 통해 모든 이미지 파일을 선택하고 나는 JQuery와 아약스 물건에 의해 업로드 과정이 될 것입니다 무슨 시작 :

$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 잘 형식의 개체 나머지 서비스에 모든 데이터를 전송해야하고, 그것은 다음과 같이 진행됩니다

$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 

을 당신이 그것을 위해 죽을 아무것도 전송하지 꽤 표준 아약스 볼 수있다. 내 레일 측에서

제가 가지고 모델 : set_picture 메소드는 아마 원시 화상 파일 데이터를 수신

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 

엔드. 임시 파일을 생성하고 데이터 내용을 여기에 쓰고 int를 self.image 속성으로 설정합니다.

이제 컨트롤러 : 난 그냥 uploaded_file 지역 변수로 들어오는 요청과이를 처리 저점 set_picture 모델의 방법에 관한 파일 데이터를 잡을이 컨트롤러에서

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 

. 마지막으로 params [: product] [: image] 원래 해시 값을 다시 설정합니다.

Paperclip 설정과 S3 amazon 통합은 꽤 표준이지만 레일즈 응용 프로그램 자체에서는 완전히 기능을 수행합니다. 일단 간단한 erb multipart/form-data를 사용하고 기본 양식을 전송하면 한 번 완벽하게 작동합니다.

이미지 매개 변수없이 dataproduct json을 보내면 모든 것이 올바르게 작동합니다. 하지만 img param과 함께 할 때 콘솔에 오류가 있습니다 !!!

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> 

나는, '% WX의 %의 시간 -format ", 코카인에 대한 문제를 많이 읽고 파악하고 내가 Paperclip.run는 ("확인 "을 실행하는 경우이 가지 방법에 의해 itselves으로 작업했습니다 % [exif : orientation] ': 파일 ", : 파일 =>"/ tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg [0 "].

다음과 같이 나타납니다. identify : JPEG 파일이 아닙니다. 0x30 0x30 '/ tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg [0'@ error/jpeg.c/EmitMessage/236]로 시작합니다.

그래서 원래의 유효한 jpg 인코딩 파일을 레일즈 애플리케이션에 "재구성"하는 방법이되어야한다고 생각합니다. 그러나 그것에 대해서는 확실하지는 않지만 그것에 대해 연구하고 있습니다.

오랫동안 유감스럽게도 다른 contentType 및 processData 아약스 설정을 추가하거나 readAsArrayBuffer() 및 readAsText()와 같은 다른 FileReader 메서드를 추가하여 스플릿없이 파일을 보내는 등 많은 작업을 해왔습니다. 다른 문자 인코딩, utf-8, ascII, base64 등등에 메타 데이터 및 메서드를 사용하는 중 ... 아무도 작동하지 않지만 정말 피곤해서 도움을 주시면 감사하겠습니다 xx

답변

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 
0

실제 문제를 견디십시오. ajax 파일 업로드 플러그인을 사용하여 파일 데이터를 보내고 싶습니다. Ajax 파일 업로드 파일은 숨겨진 i- 프레임을 제출하여 직렬화되지 않은 데이터를 전송합니다. ajax 파일 업로드 및 일반 양식 제출을 한 번 시도해보고 콘솔에서 실제 오류를 확인하십시오.

+0

감사합니다. @Sabyasachi Ghosh! 하지만 실제로 플러그인을 사용하지 않고 있습니다. FileReader API를 사용하여 파일 원시 데이터 또는 유사한 파일을 가져 와서 json 개체로 설정하고 RoR 기반의 나머지 웹 서비스로 전송했습니다. 나는 정규적인 폼 서브 미트가 작동 할 수 있다고 생각하지만, 나의 웹 클라이언트는 아약스가 가득한 것으로 생각하고 가능할 수 있다는 것을 믿는다, 나는 단지 그렇게하는 방법에 대해 고심하고있다. 나는 올바른 파일 인코딩을 설정하는 방법이 있고 그래서 클립 클립은 그것을 소비 할 수 있다고 생각한다. – marleyferreira

0

스택 추적에서 meta_request를 사용하고 있습니다. 우리는이 보석 및 jQuery 업로드와 비슷한 문제가있었습니다. meta_request없이 작동하도록하십시오. 그런 다음 메타 요청을 수정하거나 여기 티켓을 여는 것이 좋습니다. https://github.com/dejan/rails_panel/issues.

+0

@t_itchy 단서를 가져 주셔서 감사합니다! 나는 그것을 지금 점검 할 것이다. – marleyferreira

+0

그냥 meta_request에서 찢어졌지만 로그 출력이 크게 변경되지 않았습니다. 내가 갇혀있는 방법은 일반 이미지 파일 (jpg, png ..)에서 원시 데이터를 가져 와서 내 서버로 보내고, 자기 자신을 설정하는 방법에 관한 것입니다.이미지 첨부 파일로 저장하십시오. Paperclip.run ("식별", "-format '% wx % h, % [exif : orientation]': 파일", : 파일 => "tmp/temp_file20130906-2165-1t7m9i920130609-2165-1wb3pv7.jpg [ 0] ") 내 파일이 jpg 파일이 아닌 콘솔 로그 !!! 좋아, 이것이 단서처럼 보이지만, 내 Ajax 요청에 의해 보내지는 이미지의 내용을 올바른 jpg 물건으로 바꾸는 방법을 찾고있다. – marleyferreira

1

하나는 convert을 테스트하기 위해 실행중인 명령에 문자가 없습니다. "/tmp/test20130609-4953- aqzvpm20130609-4953-12ijmo6.jpg[0"에 끝 문자 ]을 붙여 넣었으므로 제대로 작동하지 않을 것으로 예상됩니다. 당신이 ] 것을 추가하면 작동하지만 난 그것을하지 않습니다 알고있는 경우

두, 물어 것입니다 : 당신이 말한 당신이 Base64로 FileReader와 JS 측에 인코딩하지만 만약 당신이하지 않는 말을하면 Base64로 디코드 그 그것. set_picture 방법에서는 데이터를 디코딩해야합니다. 그게 당신에게 필요한 것을 얻기에 더 가깝습니다. 파일을 convert을 통해 보내지 않고 서버를 통과해도 문제가 없는지 확인할 수도 있습니다.

+0

아주 좋은 @jyurek! 사실 내 코드에는 여분의 "]"결말이 있습니다. 여기에 잘못된 복사/붙여 넣기로 엉망이되었습니다. 그래, 내가 Base64decoding에 대해 읽었지만 일단 Base64 인코딩 된 문자열 버퍼가 텍스트 편집기에서 열면 일반 jpg 파일처럼 보이면 조금 혼란 스럽다. 사실 나는 이미 서버 측에 Base64Decoding을 보내고 싶다고 생각했기 때문에 서버 측에서 디코드 할 필요는 없지만 실제로 효과가 있는지는 잘 모르겠습니다. 나는 당신이 말했듯이 서버 측에서 그것을 시도 할 것이다. 최고의 남자에 관해서! – marleyferreira