【问题标题】:Submit Not Triggering Appropriate Accept Headers Using form_remote_tag使用 form_remote_tag 提交未触发适当的接受标头
【发布时间】:2009-12-19 04:28:56
【问题描述】:

form_remote_tag 似乎生成了正确的 html,但渲染的是 format.html 而不是 format.js。呈现 format.html 而不是 format.js 的两个最常见的答案是将文件 *.rjs 重命名为 *.js.rjs 并确保实际加载了 javascript 文件。这两项都已完成。如果有任何其他信息可以提供,请告诉我。

[编辑] create.js.rjs 已在下面添加。 [/编辑]

Rails 2.3.2

查看/项目/show.html.erb

<%= form_remote_tag :url => { :controller => :milestones, :action => :create }
    #:update => 'milestone-list',
    #:url => { :controller => "milestones", :action => :ajax_create},
    #:position => 'bottom'
%>

<%= render :partial => 'milestones/form' %>
<input type="hidden" id="milestone_project_id" name="milestone[project_id]" value="<%=@project.id %>" />

<%= submit_tag 'Add Milestone' %>

milestones_controller.rb

def create
 @milestone = Milestone.new(params[:milestone])

 respond_to do |format|
    if @milestone.save
        flash[:notice] = 'Milestone was successfully created.'
        format.js   {render :layout => false }
        format.html { render :show }#redirect_to(@milestone) }
        format.xml  { render :xml => @milestone, :status => :created, :location => @milestone }
    else
        format.html { render :action => "new" }
        format.xml  { render :xml => @milestone.errors, :status => :unprocessable_entity }
    end
 end
end

标题

(域名和ips已更改。服务器是杂种服务器,apache设置为代理)

*  ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
* HOST: 127.0.0.1:8004
* X_FORWARDED_HOST: slate.project.mydevserver.com
* VIA: 1.1 project.mydevserver.com
* USER_AGENT: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
* ACCEPT_LANGUAGE: en-us,en;q=0.5
* REFERER: http://slate.project.mydevserver.com/projects/2
* VERSION: HTTP/1.1
* X_FORWARDED_SERVER: project.mydevserver.com
* X_FORWARDED_FOR: 1.2.3.4
* ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.7
* CONNECTION: Keep-Alive
* ACCEPT_ENCODING: gzip,deflate

生成的html

<form action="/milestones" method="post" onsubmit="new Ajax.Request('/milestones', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
<div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="wTS9QPqFiGvP3RVlvKsA49Z6xtEGH9gmcLP//XC0whc=" /></div>

Title: <input id="milestone_title" name="milestone[title]" size="30" type="text" /><br />
Description: <input id="milestone_description" name="milestone[description]" size="30" type="text" /><br />
Days: <input id="milestone_days" name="milestone[days]" size="30" type="text" /><br />

<input type="hidden" id="milestone_project_id" name="milestone[project_id]" value="2" />

<input name="commit" type="submit" value="Add Milestone" />
</form>

create.js.rjs

page.insert_html :bottom, 'milestone_list', "Hi"

【问题讨论】:

  • 您能发布相关的 RJS 文件吗?那里可能有问题。

标签: ruby-on-rails ajax


【解决方案1】:

您可以通过将 :format => :js 添加到 url 哈希来强制格式为 javascript 来轻松检查您的代码是否正常。它会显式地将格式添加到 url,从而强制呈现 javascript,但它会破坏禁用 javascript 的浏览器的优雅降级。如果您想保留该功能 - 我相信您应该查看您的代理 (apache) 配置,如上所述 - 显然它与您的标题混淆了。

尝试在浏览器发送请求时捕获请求(使用 Firebug 或用于 Firefox 的 LiveHTTPHeaders)并将其与您在服务器端看到的请求进行比较,我相信您会发现问题存在。

【讨论】:

  • 将它添加到 url 给了我一个“找不到 create.js.erb”的错误我将 create.js.rjs 复制到 create.js.erb 并且正如预期的那样,它只是显示了内容文件而不是运行它。
  • 我打印到响应请求的 html 页面和 LiveHTTPHeaders 之间的标头是相同的。我感觉可能有一些微小的实施更改不在 Rails 文档中。
  • 我给你赏金,因为你是唯一解决标题问题的人。它仍然没有修复,但至少我可以在这里问一个不同的问题。 (当使用 :format => :js 时,为什么 rails 会寻找 create.js.erb 而不是 create.js.rjs?)谢谢!明天去找。
  • 当您强制响应格式时,您应该禁用基于接受标头的自动 mime 类型猜测,否则您的强制格式将无法正常工作。似乎由于某种原因您启用了接受标头处理,尽管自 rails 2.2 起它应该默认禁用。使用 config.action_controller.use_accept_header = false 来执行此操作 - 在此处查看更多详细信息 guides.rubyonrails.org/…
【解决方案2】:

您是否有可能在您正在测试的浏览器中禁用了 Javascript?这可以解释你的结果。

【讨论】:

  • 超过 15 个字符如何拒绝。
  • 我没想到它会是正确的答案,但这是我能想到的唯一可以描述您的问题的方法。其他一切看起来都不错。
  • 没问题。这是强制性的“是否已插入”问题。这就是让我把头撞在墙上的原因。我真的希望这是一个简单的答案!也许它是杂种问题的 apache 代理。嗯。
  • Firebug 或类似工具说您正在执行什么样的请求?
  • 请求的完整 URL 是什么?我看到了您的推荐人标头,但正如您所提到的,它可能与您的代理有关。您是否有可能跨子域或类似的东西发出请求?不幸的是,我对 Apache 配置或读取所有请求标头的了解不够,所以除此之外我还被窃听。您上面的代码非常适合我(请注意,在 2.3.5 中)。
【解决方案3】:

您是否尝试过从 format.js 中删除 {render :layout =&gt; false } 块并执行类似的操作

...
...
format.js
format.html { render :show }#redirect_to(@milestone) }
...

据我了解,RJS 不处理布局,因为它不会在其中产生,但我可能错了。但我个人之前从未在我的 js 响应中实际使用过 :layout 选项。

此外,您的渲染调用缺少要渲染的“内容”。喜欢...

render :js => "alert('this is javascript')"
render :action => "some_action"
render :xml => ....

【讨论】:

  • 是的,我已尝试删除该块。它不会错过要渲染的内容。它应该运行 create.js.rjs,并在原始页面上显示它。问题是它使用的是 format.html 而不是 format.js,因为接受标头请求的是 text/html 而不是 text/javascript
  • 您是否尝试过仅在 Mongrel(可能是本地)上单独运行应用程序,而不使用 Apache + Mongrel 组合?您的代码看起来很干净,所以当请求通过您的 Apache + Mongrel 设置时,可能有一些东西正在改变标头。另外,我敢肯定你可能尝试过这个。但是,如果您不在“开发”中,您是否在每次部署/更改后重新启动应用程序?
  • 它在一个带有 nno xwindows 的 linux 机器上。我还没有听说过启用 javascript 的文本浏览器。不幸的是,赏金在一个小时后结束,所以我无法及时安排 Mongrel 指出。
【解决方案4】:

一个想法是,您可以在控制器中重写您的创建操作,以包含一个测试以查看请求是否为 XHR(这是 detailed further 在文档中),这是一个简化版本:

def create

  @milestone = Milestone.new(params[:milestone])

  if @milestone.save
    if request.xhr?
      render :update do |page|
        page.insert_html :bottom, 'milestone_list', "Hi"
      end
    else
      respond_to do |format|
        flash[:notice] = "Milestone saved"
        format.html
      end
    end
  else
    respond_to do |format|
      flash[:error] = "There was a problem saving the milestone"
      format.html { render :action => :new }
    end
  end

end

这可能会导致一些干燥,但你应该明白这一点。

【讨论】:

  • request.xhr 完全失败。这是同样的问题。在这种情况下,应该将 TIMTOWDI 重命名为 TIMTOWTGTSE(获得相同错误的方法不止一种)。 :D
【解决方案5】:

如果您运行rake:routes,您使用的路线是否以(.:format) 结束?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多