使用malsup的respond_to ... format.json和jQuery Form Plugin

Top*_*gio 5 json file-upload ruby-on-rails jquery-forms-plugin

我在使用jQuery Form Plugin与文件上传字段正常工作时遇到了一些麻烦.当我使用插件提交没有文件上传字段的表单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);
});
Run Code Online (Sandbox Code Playgroud)

Tse*_*ing 7

需要做一些事情才能使jQuery Form插件适用于带有JSON响应的文件上传.在javascript中,.ajaxForm的选项应该具有:

dataType: 'json', // evaluate return as JSON
Run Code Online (Sandbox Code Playgroud)

浏览器需要告诉Rails操作将内容作为JSON返回,一种方法是在文件上传表单模板中添加隐藏格式输入字段:

<%= hidden_field_tag 'format', 'json' %>
Run Code Online (Sandbox Code Playgroud)

然后,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"
    }
  }
Run Code Online (Sandbox Code Playgroud)


小智 1

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

请参阅 malsup 在该线程中的回答

他说:

文件上传不使用ajax,表单插件只是让它以这种方式显示。上传文件时会发生真正的浏览器提交。