服务器已发送响应,但客户端未加载已发送的内容

时间:2018-09-28 13:25:29

标签: javascript node.js express browser

我有简单的节点服务器(nodejs + express + ejs呈现),当用户尝试加载特定的页面服务器时,它会发送已编译的html并作为响应发送。

为了跟踪用户,我添加了2个计数器

a。服务器收到该页面的请求时,计数器会增加

b。当客户端加载页面时,页面包含一些代码,这些代码会将HTTP请求返回给我用作计数器的服务器

现在的问题是,随着时间的流逝,sentResponse计数器和clientLoad计数器之间的差值增加得太多,以至于我得到sentResponse = 7000clientLoad = 3600

关于可能导致这种行为的任何建议

注意:在请求到达服务器之前,我也已经设置了Cloudfare,我暂停了它,但是仍然有很大的不同吗?

注意:我还注意到很多用户经常在4秒之内多次向该页面发出请求,但是我确定我发送的是有效的html,而且差异几乎是50%,所以我认为并不是每个访问的用户该页面在4s内按ctrl + r 2次或更多次。

代码:

server.js

app.get('/dashboard', (res, res) => {
    ...
    ...
    ...

    Tracker.incrementCount('sentResponse');
    res.render(page.ejs, {...});
});

app.get('/client-load-start', (req, res) => {
    Tracker.incrementCount('clientLoadStart');
    res.send(200);
});

page.ejs

<html>
    <head>
        ...
        <script src='/client-load-start?version=<some_random_4_digit_number>'></script>
        ...
    </head>

    <body>
        ...
        ...
    </body>
</html>

3 个答案:

答案 0 :(得分:1)

我可以考虑以下几种可能导致计数不同的原因。

  • 设置缓存标头(Cache-Control)可能会导致浏览器缓存请求。
  • 客户端的浏览器中未启用JS,因此不可能对服务器进行AJAX调用以更新clientLoad计数器(这可能性较小,但仍然是可能性之一)。
  • 人们甚至在页面加载之前就与页面进行了交互,从而导致AJAX调用无法触发。人们在页面可以加载之前重新加载了页面。

如果您只是想跟踪

答案 1 :(得分:1)

您可以尝试使用缓存清除方法。每次浏览器加载/dashboard时,浏览器都会为您的/client-load-start路由获取脚本源。问题在于,仅在清除浏览器的缓存时或第一次加载网站时才请求/client-load-start。这将导致两个计数随时间变化很大的问题。

尝试使浏览器认为/client-load-start是需要下载的新脚本。您可以通过将查询参数添加到src来实现。

<script src='/client-load-start?<%- Date.now()%>=1'></script>

每次浏览器转到/dashboard时,它都会尝试下载新脚本,因为查询参数已更改,从而破坏了缓存。

答案 2 :(得分:0)

事件顺序

  1. 浏览器请求/dashboard
  2. 服务器增加sentResponse,呈现page.ejs并将其发送到浏览器
  3. 浏览器收到page.ejs并检测到<script>标签
  4. 浏览器检查脚本URL是否在浏览器缓存中
    • 如果在缓存中找到脚本URL,则序列到此结束;否则,序列到此结束。 clientLoad保持不变
  5. 浏览器从您的服务器请求脚本
  6. 服务器执行get请求,增加clientLoad

问题

此处的“问题”是浏览器-或浏览器与服务器之间的任何代理-都会缓存返回的脚本,除非您另行指示。

请注意,在大多数情况下,缓存实际上是预期的和预期的行为。这也是浏览器的默认行为。

解决方案

要指示浏览器(或代理)避免缓存文件,可以设置cache control headers

app.get('/client-load-start', (req, res) => {
    Tracker.incrementCount('clientLoadStart');
    res
       .set('cache-control', 'max-age=0; private; no-cache')
       .send(200);
});

这将指示浏览器从不缓存请求,并始终获取新副本,从而使每个请求都增加clientLoadStart

另一种方式是“ cache busting”,这意味着您有意更改脚本的URL,例如通过像上面一样添加一个随机数,从而“破坏”缓存键。