2010-02-09 17 views
5

我有一點麻煩讓jQuery Form Plugin與文件上傳領域正常工作。當我使用該插件提交沒有文件上傳字段的表單時,respond_to do |format|塊的format.json部分被正確調用。但是,通過添加文件上傳字段,它只執行format.html部分,這使得我的JavaScript代碼認爲發生了錯誤。使用respond_to ... format.json和jQuery表單插件由malsup

有沒有人遇到過這種情況,或知道強制插件總是使用json的方法?或者,我可以修改插件用來強制Rails渲染json的url嗎?

非常感謝您的幫助!代碼如下:

# app/controllers/details_controller.rb 
def create 
    @detail = Detail.new(params[:detail]) 

    style = params[:detail_style].to_sym || :thumb 
    data = { :id => '5', :url => 'test.rails' } 

    respond_to do |format| 
    if @detail.save 
     flash[:notice] = 'Your image has been saved.' 
     data = { :id => @detail.id, :url => @detail.data.url(style) } 

     format.html { redirect_to :action => 'index' } 
     format.json { render :json => "<textarea>#{data.to_json}</textarea>", :status => :created } 
    else 
     format.html { render :action => 'new' } 
     format.json { render :json => @detail.errors, :status => :unprocessable_entity } 
    end 
    end 
end 

/* app/views/sidebar/_details.html.erb (excerpt) */ 

<% form_for(Detail.new, :html => { :multipart => true }) do |f| %> 
    <%= hidden_field_tag 'detail_style', 'thumb' %> 

    <%= f.label :image, "Recent Images" %> 
    <%= f.file_field :image%> 

    <p> 
    <%= f.submit "Upload" %> 
    </p> 
<% end %> 

<script> 
$(document).ready(function() { 
    var options = { 
    dataType: 'json', 

    success: function(json, statusText) { 
     console.log("success: " + json); 
    }, 

    error: function(xhr, statusText, errorThrown) { 
     console.log("error: " + xhr.responseText); 
    } 
    }; 

    $('#new_detail').ajaxForm(options); 
}); 

回答

1

顯然,使用ajaxSubmit並且上傳文件時,設置Accept標頭是不可能的。

請參閱malsup在此線程中的答案here

他說:

文件上傳不使用AJAX,形式插件只讓它看起來是 方式。上傳文件時會發生真正的瀏覽器提交。

+0

我嘗試在beforeSend回調中設置Accept標頭,但這沒有效果。 當我看着jQuery.form的代碼時,傳遞給beforeSend的XHR對象有一個初始化爲「setRequestHeader」的空函數。不過,我正在查看該文件的2.16版本,也許在以後的版本中有變化。 – Prashant 2010-05-30 09:16:18

1

你可以使用螢火蟲檢查服務器的帖子,並在此處粘貼請求標題。我們期待看到Accept頭被設置爲json。另外,你使用的是什麼版本的導軌?

+0

不幸的是,這是問題的一部分。看起來這個插件使用了一個iframe來提交表單,因此它並沒有在Firebug中顯示出來(我不是很確定這是問題所在,但它並沒有顯示出來,而且我知道它使用的是iframe ...)。當它正常工作時,我驗證了標題設置爲json。哦,我正在使用Rails 2.3.5。 – 2010-02-09 16:31:50

1

我還不確定它爲什麼不起作用,但我嘗試了很多東西,最終找到了解決方案。

我試着改變網址,在最後加入.json,這迫使Rails渲染format.json塊,但它讓我覺得我想下載一個文件讓我的瀏覽器感到困惑。

所以,我然後嘗試通過傳遞參數​​修改網址,但不幸的是做了完全相同的事情。

最後,我試圖改變format.json只是format.js(JavaScript)的和添加.js的url,但仍然使用相同的render :json => ...,我與我的jQuery的電話設置dataType參數json之前一起。即使它不是最優化的解決方案,這似乎也能正常工作。

我希望別人認爲這有用。如果我找到正確的答案,我會再次發佈。與此同時,如果有其他人有正確的答案,讓我知道,我會接受你的!

+0

在Firefox中完美運行,但它在Safari(5.0.5)中產生警告。 – 2011-05-11 15:07:07

7

需要做幾件事才能讓jQuery Form插件能夠用JSON響應來上傳文件。 在JavaScript中,.ajaxForm的選項應該有:

dataType: 'json', // evaluate return as JSON 

的瀏覽器需要告訴Rails的行動來回報內容,JSON, 一種方式做,這是在文件中添加一個隱藏的格式輸入字段上傳表單模板:

<%= hidden_field_tag 'format', 'json' %> 

Rails操作將在respond_to塊內運行format.json方法。

在服務器動作標籤

  • 封裝JSON, .ajaxForm那裏展開串和eval JSON正確
  • 集中返回的內容類型爲「text/html的」,否則某些瀏覽器 ( Firefox)會嘗試將返回下載到文件中。

例如

respond_to do |format| 
    format.json { 
      render :json => "<textarea>#{data.to_json}</textarea>", :content_type => "text/html" 
    } 
    } 
2

我爲此問題做了一個解決方法。我測試了這個解決方案只使用Rails 3,但也許它的工作原理也爲2.3.x版本

的解決方案很簡單:

!#javascript 

$('form#my_form').live('submit',function(){ 
$(this).ajaxForm({ dataType: "script", success: processJson}) 
return false; 
}) 

//data arrive as a string but we can parse it correctly 

function processJson(data, statusText, xhr, $form){ 
my_data_parsed = JSON.parse(data); 

    } 

!#ruby 
def create 
.... 
render :js => { :status => false,:messages => @myobject.errors.full_messages}.to_json 

end