[英]Strange behavior with multiple ajax requests to the same URL
我在CherryPy服务器中构造了一个奇怪的情况,我希望得到一些帮助来了解确切的情况以及原因。 这是server.py
:
import cherrypy
import os
import threading
class Root(object):
def __init__(self):
self.count = 0;
self.lock = threading.Lock()
@cherrypy.expose
def app(self):
with self.lock:
self.count += 1
return "Call #%d" % (self.count)
if __name__ == '__main__':
cherrypy.quickstart(Root(), "/", {"/": { "tools.staticdir.on": True,
"tools.staticdir.dir": os.getcwd() } })
这是一个非常简单的应用程序,其某些状态受互斥锁保护。 这是index.html
:
<!doctype html>
<script src=http://code.jquery.com/jquery-1.8.2.js></script>
<script src=index.js></script>
(HTML可以这么稀疏-可以看Paul Irish的演讲 )这是index.js
:
function request() {
var cb = function (response) {
console.log(response);
};
$.ajax({
url: "/app",
success: cb
});
}
function go_slow(N, delay) {
if (N > 0) {
request();
window.setTimeout(go_slow, delay, N - 1, delay);
}
}
function go_fast(N) {
var i;
for (i = 0; i < N; i++) {
request();
}
}
window.onload = function () {
//go_slow(100, 0);
go_fast(100);
};
所有这些文件应放在同一目录中。 当我启动CherryPy服务器,然后访问http://localhost:8080/index.html
,控制台将显示短语“ Call#1” 100次,而CherryPy日志将显示一个对“ / app”的GET请求。 在Firefox中,我看到几个连续的控制台消息,分别显示“#1”到“#100”。 Firefox的行为符合我的预期,因为我发出了100个明确的ajax请求,并且与这些请求相关的函数每次都将返回不同的结果。
如果不是go_fast()
我调用go_slow()
-使用“ trampolining”(我认为这是一个变种)来强制ajax请求在不同时间从单独的函数调用中发出的变体-那么我通过“#1” Chrome和Firefox上的“#100”行为。
最后,如果我在CherryPy服务器中修改app()
方法以接受一个参数,然后它会忽略该参数,就像这样(请注意, i
参数不会在其他任何地方出现):
@cherrypy.expose
def app(self, i):
with self.lock:
self.count += 1
return "Call #%d" % (self.count)
然后我通过更改request()
和go_fast()
来安排go_fast()
函数向"/app/" + i"
(其中i
是循环索引)发出ajax请求,而不只是"/app"
:
function request(i) {
var cb = function (response) {
console.log(response);
};
$.ajax({
url: "/app/" + i,
success: cb
});
}
function go_fast(N) {
var i;
for (i = 0; i < N; i++) {
request(i);
}
}
然后我再次通过“#100”获得“#1”行为。 相反,如果我修改函数以使用例如"/app/7"
作为URL(即,将上面代码段中的"/app/" + i
替换为"/app/7"
),那么我会得到100次“如初始示例中所示,调用“ 1”。
在我看来,很像是某些东西 “缓存”了最初情况下实际发出的一个且唯一的ajax请求的结果(在这里我只看到“ Call#1” 100次)。 Chrome控制台中的“网络”标签仅显示了一个接收到状态代码为“ 200 OK”的ajax请求,据我所知,您必须在CherryPy中显式启用服务器端缓存。 好奇的是,在这种情况下,Firefox提供了预期的行为。
在其他情况下,由于一个或另一个原因,这种“缓存”机制被破坏了。 Trampolining可能会导致浏览器抛弃ajax请求的即时上下文,从而阻止它“记住”先前对同一URL的请求,同时将URL构造为需要位置参数,只是将每个请求赋予唯一的URL,强制发出实际请求,而不是使用任何缓存机制。
谁能具体解释这是怎么回事? 这仅仅是有关Chrome如何在短时间内处理许多Ajax请求的特性吗? 还是这种情况是拥有有状态的ajax资源的致命问题?
我认为这是一种与cache: false
结合使用的竞争条件cache: false
客户端的cache: false
选项,请记住您的对象Root
在线程池内共享。
在时间A
您修改self.count
,在时间A
另一个X请求(线程)返回您新修改的参数,它们是在with
块上的时间A - 1
上with
并且没有在此特定请求上返回该新计数。
当正在修改并从with语句中退出的另一个请求已经在返回中时,那么决定是否重复返回数字的原因是cherrypy线程池的处理吞吐量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.