5

我在让jQuery 表单插件与文件上传字段正常工作时遇到了一点麻烦。当我使用插件提交没有文件上传字段的表单时,块的format.json部分respond_to do |format|被正确调用。但是,通过添加文件上传字段,它只执行format.html使我的 javascript 代码认为发生错误的部分。

有没有人遇到过这种情况或知道强制插件始终使用 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);
});
4

5 回答 5

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 将解开字符串并正确评估 JSON
  • 将返回内容类型设置为“text/html”,否则某些浏览器(Firefox)会尝试将返回内容下载到文件中。

例如

  respond_to do |format|
    format.json {
          render :json => "<textarea>#{data.to_json}</textarea>", :content_type => "text/html"
    }
  }
于 2010-09-17T17:59:55.507 回答
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 
于 2011-01-26T18:52:39.113 回答
1

您能否使用 firebug 检查发往服务器的帖子,并在此处粘贴请求标头。我们希望看到 Accept 标头设置为 json。另外,您使用的是什么版本的导轨?

于 2010-02-09T15:58:34.777 回答
1

我仍然不确定为什么它不起作用,但我尝试了很多东西,终于找到了解决方案。

.json我尝试通过添加强制 Rails 呈现块的末尾来更改 url format.json,但它让我的浏览器认为我想下载一个文件而混淆了我的浏览器。

所以,然后我尝试通过传递参数来修改 url ?format=json,不幸的是,它做了完全相同的事情。

最后,我尝试将format.jsonjQueryformat.js调用中的参数设置为. 即使它不是最佳解决方案,这似乎也有效。.jsrender :json => ...dataTypejson

我希望其他人觉得这很有用。如果我找到正确的答案,我会再次发布。同时,如果其他人有正确的答案,请告诉我,我会接受你的!

于 2010-02-11T02:54:49.950 回答
1

显然,当使用 ajaxSubmit 并上传文件时,无法设置 Accept 标头。

在此线程中查看 malsup 的答案。

他说:

文件上传不使用 ajax,表单插件只会让它看起来那样。上传文件时会发生真正的浏览器提交。

于 2010-05-30T09:12:51.487 回答