[英]Ruby on Rails: Figuring out 406 error / lack of redirect with AJAXified form
我有一个带有“ Article”支架的项目-其中包括缩略图的回形针文件字段-团队中的其他人抱怨提交表单时必须如何再次将文件添加到字段中,并且验证错误是由于缺少另一个字段上的数据而触发。
考虑到这是由于浏览器的限制所致,我在表单中添加了一个remote => true以及一个error.js.erb文件,从而确定了如果不必重新加载页面的情况下文件字段仍然存在。 不幸的是,事实并非如此,因为我读到出于安全原因,浏览器无法通过AJAX处理多部分表单/文件。 但是,我随后发现了Remotipart宝石 ,可以解决此问题。 因此,应用程序的相关部分如下所示:
_form.html.erb
<%= form_for(@article, :html => { :multipart => true }, :remote => TRUE) do |f| %>
<div id="errors"></div>
<%= f.text_field :title %>
<%= f.text_area :body %>
<%= f.file_field(:photo) %>
<%= f.submit %>
<% end %>
article_controller.rb (创建操作)
def create
@article = Article.new(params[:article])
respond_to do |format|
if @article.save
format.html { redirect_to(@article, :notice => 'Article was successfully created.') }
format.xml { render :xml => @article, :status => :created, :location => @article }
else
format.html { render :action => "new" }
format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
format.js { render 'errors', :locals => { :item => @article } }
end
end
end
errors.js.erb
<%= remotipart_response do %>
$("#errors").empty().append('<div id="error_explanation"><h2><%= pluralize(item.errors.count, "error") %> prohibited this article from being saved:</h2><ul></ul></div>');
<% item.errors.full_messages.each do |msg| %>
$("#error_explanation ul").append("<li><%= escape_javascript(msg) %></li>");
<% end %>
<% end %>
因此,基本上,如果存在验证错误,那么js文件会将这些错误添加到表单上的错误div上。 此外,如果填写了文件字段,则该字段仍然存在。所有工作都可以:它确实在数据库中创建了内容并上传了文件,或者在某些验证失败的情况下抛出了错误而不会丢失文件字段,但是仍然存在一个问题。
提交表单并上传文件时,我的日志中出现406不允许错误,而没有重定向到显示页面。 如果表单没有上载文件,则日志将返回200 OK,但是页面也不会重定向到show操作。
在Google和其他SO线程上搜寻之后,我发现这部分代码应该可以将其传递给正确的标头(是的,jQuery已安装并在application.js之前运行)...
application.js
jQuery.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})
...不幸的是,它不起作用。 我没有任何想法,关于如何解决406问题并使其正确重定向的任何建议?
我认为您这样做太复杂了,为什么不集中精力防止用户在出现错误后再次上传文件。 用户继续以他们快乐的方式前进,而您不必为丑陋的JavaScript黑客所困扰。
存储文件,然后将用户重定向到填写了文件字段的创建页面。
直到现在还没有解决这个问题,但是我终于解决了这个问题。 首先,我删除了application.js代码。 其次,通过在response_to的保存成功中包含format.js解决了406重定向的问题。
respond_to do |format|
if @article.save
format.js
format.html { [...] }
else
[...]
end
end
唯一的问题是,即使将redirect_to放置在format.js中,页面也根本不会重定向。 它确实触发了一个create.js.erb文件,所以在其中,我放了...
window.location.replace("/articles");
...以在加载create.js.erb时启动重定向。 我希望它通过控制器进行响应和重定向,而不是通过JavaScript进行重定向,但是我还没有看到针对此问题的有效解决方案(我研究过的涉及request.xhr代码的所有其他方法都根本无效)。 但这有效。
但是,这样做的另一个好处是,我可以通过节省文章来提高创意,例如在重定向到文章索引之前预览“显示”页面几秒钟,等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.