我有一个rails应用程序,通过这个ajax请求跨域(我用rack-cors来完成这个跨域请求而不用jsonp):它用html响应
//to ensure cache=true gets passed
$.ajaxPrefilter('script', function(options) {
options.cache = true;
});
//ajax requests html
$.ajax({
beforeSend: function (xhr) {
xhr.setRequestHeader ('Authorization', api_key);
},
dataType: 'html',
type: 'GET',
url: url+'/gwsearch/ajax_search?d1='+d1_val+'&d2='+d2_val,
crossDomain: true,
success:function(result){
$("#display").html(result);
},
error: function(result) {
$('#display').html('Unauthorized client.');
}
它使用#display
中显示的HTML进行响应。它有这个脚本标签包含在html
<script src="http://localhost:3000/assets/application.js" type="text/javascript"></script>
我在新显示的rails应用程序上有输入按钮,它们看起来像这样:
<%= form_tag plans_collapse_plans_path, :method => 'post', :remote => true do %>
<%= hidden_field_tag(:plangroup_id, plangroup.id) %>
<%= image_submit_tag "collapse.png" %>
<% end %>
点击输入按钮进行POST。问题是输入按钮将按照我请求跨域rails应用程序的次数进行POST。如果我已经请求应用程序5次,当我点击应用程序上的输入按钮时,它将POST 5次。
无论我发送多少次初始ajax请求,我仍然只有一个application.js存在;它不会被多次物理缓存。
编辑:正如您所看到的,这就是我的缓存看起来只有一个application.js:
collapse_tplans POSTs对应于同一个application.js文件,同一行。如果我已经加载了6次初始ajax请求,那么我将从application.js中获得6个collapse_tplan POST
我的猜测是,正在发送的html页面中的脚本标记正在初始化jquery的新版本(因为jquery包含在application.js中),并且还可能与application.js中正在加载的其他内容重复。它是通过脚本标签发送的。话虽如此,在Chrome in Network中,无论执行ajax请求多少次,我都只能看到一次请求application.js。
有什么想法吗?我需要我的输入按钮只发一次,就像它应该做的那样。我真的很难过这个。
答案 0 :(得分:3)
由于您在表单上使用remote:true,我的理论是每次加载脚本时rails.js都会在文档元素上附加委托事件。 5次加载= 5次事件= 5次ajax调用。
要修复它,你可以:
尝试:(我猜这里)
success:function(result){
$(document).undelegate('submit.rails');
$("#display").html(result);
},
说明:
每次运行rails.js时,都会在文档的事件堆栈中添加submit.rails事件。当您将html插入页面时,rails.js代码会运行。因此,我们首先取消事件,然后重新加载事件。
答案 1 :(得分:3)
正如@natedavisolds所述,我猜你的application.js
脚本执行了5次,而你的click
或button
处理程序的submit
hanlder执行了form
附加了5次。
application.js
仅被请求一次这一事实并不能告诉您执行了多少次。
尝试在application.js
脚本的开头添加以下行:
console.log('application.js executed');
并检查您的浏览器控制台,查看该消息显示的次数。
从您的脚本名称application.js
开始,我想这是为了初始化整个页面,而您的ajax请求看起来只是填充了#display
节点的搜索结果。
您必须重构application.js文件:
application.js
文件中的代码,并将代码分为两部分:涉及设置#display
div的部分和其余部分。 results.js
(或您认为合适的任何名称)。 <script src="application.js">
请求的响应中删除/gwsearch/ajax_search
节点,并将其替换为<script src="results.js">
节点,而不是答案 2 :(得分:0)
这个问题的答案是阻止我的应用程序服务application.js
并将其托管在客户端上。我通过以下方式做到了这一点:
应用程序/视图/布局/ application.html.erb
我注释掉了提供application.js
<!--# <%= javascript_include_tag "application" %> -->
在我的客户中,我添加了
<script src="https://myapp.herokuapp.com/assets/application.js"></script>
因此,客户端提供application.js
,并且在没有application.js
的情况下发送rails html响应。希望这对每个人都有意义,这需要我一段时间拼凑起来!