【问题标题】:Using respond_to ... format.json and jQuery Form Plugin by malsupmalsup 使用 respond_to ... format.json 和 jQuery Form Plugin
【发布时间】:2010-02-09 14:53:03
【问题描述】:

jQuery Form Plugin 与文件上传字段一起正常工作有点麻烦。当我使用插件提交没有文件上传字段的表单时,respond_to do |format| 块的format.json 部分被正确调用。但是,通过添加文件上传字段,它只执行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);
});

【问题讨论】:

    标签: ruby-on-rails json file-upload jquery-forms-plugin


    【解决方案1】:

    要使 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"
        }
      }
    

    【讨论】:

      【解决方案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 
      

      【讨论】:

        【解决方案3】:

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

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

        他说:

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

        【讨论】:

        • 我尝试在 beforeSend 回调中设置 Accept 标头,但这没有效果。当我查看 jQuery.form 的代码时,传递给 beforeSend 的 XHR 对象有一个初始化为“setRequestHeader”的空函数。不过我看的是2.16版本的文件,可能后面的版本有变化。
        【解决方案4】:

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

        【讨论】:

        • 不幸的是,这是问题的一部分。似乎该插件正在使用 iframe 提交表单,因此,它没有出现在 Firebug 中(老实说,我不确定这是不是问题,但它没有出现,而且我知道它使用的是 iframe 所以...)。当它正常工作时,我验证了标头设置为 json。哦,我正在使用 Rails 2.3.5。
        【解决方案5】:

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

        我尝试通过在末尾添加 .json 来更改 URL,这迫使 Rails 呈现 format.json 块,但它让我的浏览器误以为我想下载一个文件。

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

        最终,我尝试将 format.json 更改为仅 format.js (Javascript) 并将 .js 添加到 url,但仍然使用与我之前相同的 render :json =&gt; ... 并设置 dataType 参数我对json 的 jQuery 调用。即使它不是最佳解决方案,这似乎也有效。

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

        【讨论】:

        • 在 Firefox 中运行良好,但在 Safari (5.0.5) 中确实会产生警告。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多