简体   繁体   English

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

[英]Server sent response but Client not loading the sent content

I have simple node server (nodejs + express + ejs rendering) , when user tried to load a particular page server sends that compiled html and sends that in response. 我有简单的节点服务器(nodejs + express + ejs呈现) ,当用户尝试加载特定的页面服务器时,发送该编译的html并发送该响应。

In order to track users I have added 2 counters 为了跟踪用户,我添加了2个计数器

a. 一个。 counter which increments when server receives request for that page 计数器,当服务器收到该页面的请求时递增

b. when client loads the page it contains one some code which will make HTTP requests back to my server which I use as counter 当客户端加载页面时,它包含一些代码,这些代码会将HTTP请求返回到我用作计数器的服务器

Now the issue is that as time passes on the difference between sentResponse counter and clientLoad counter increases increases so much so that I get sentResponse = 7000 and clientLoad = 3600 . 现在问题是随着时间的推移, sentResponse计数器和clientLoad计数器之间的差异增加了很多,所以我得到sentResponse = 7000clientLoad = 3600

Any suggesstions on what could cause that kind of behavior 关于什么可能导致这种行为的任何建议

Note: I also have setup Cloudfare before requests reaches my server and I paused it but still I was getting huge differences ? 注意:在请求到达我的服务器之前我也设置了Cloudfare并且我暂停了它但是我仍然遇到了巨大的差异?

Note: I also noticed that lots of users are making requests to the page frequently like multiple times under 4s but I am sure that I am sending valid html and I different is almost 50% so I dont think that every user that visits the page is pressing ctrl+r 2 or more times under 4s. 注意:我也注意到很多用户经常在4s以下多次向页面发出请求,但我确信我发送的是有效的html而且我的差异几乎是50%所以我不认为每个访问该页面的用户都是在4s下按ctrl + r 2次或更多次。

Code: 码:

server.js 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 page.ejs

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

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

I can think of the following possibilities on why the count could be different. 我可以想到为什么计数可能不同的以下可能性。

  • Setting caching headers (Cache-Control) could cause the browser to cache requests. 设置缓存标头(Cache-Control)可能会导致浏览器缓存请求。
  • JS is not enabled in client's browser and so there is no possibility in making an AJAX call to the server to update clientLoad counter (This is less possible , but still is one of the possibility). JS没有在客户端的浏览器中启用,因此不可能对服务器进行AJAX调用来更新clientLoad计数器(这是不太可能的,但仍然是可能的一种)。
  • People interacted with the page even before the page loaded causing the AJAX call to not fire. 人们甚至在加载页面之前就与页面进行了交互,导致AJAX调用无法触发。 People reloaded the page before the page could load. 人们在页面加载之前重新加载页面。

If you are simply looking to track 如果你只是想跟踪

You can try to use cache-busting methods. 您可以尝试使用缓存清除方法。 Every time the browser loads /dashboard the browser is getting a script source to your /client-load-start route. 每次浏览器加载/dashboard ,浏览器都会获得/client-load-start路由的脚本源。 The problem is the only time /client-load-start is being requested is when the browser's cache is cleared, or the first time the site loads. 问题是唯一的时间/client-load-start是在清除浏览器的缓存时,还是第一次加载站点时。 This will cause the problem where the two counts can differ greatly over time. 这将导致两个计数随时间变化很大的问题。

Try to make the browser think /client-load-start is a new script that needs to be downloaded. 尝试让浏览器认为/client-load-start是一个需要下载的新脚本。 You can do this by adding query parameters to the src. 您可以通过向src添加查询参数来完成此操作。

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

Every time the browser goes to /dashboard it'll attempt to download the new script because the query parameters have changed thus busting the cache. 每次浏览器转到/dashboard它都会尝试下载新脚本,因为查询参数已更改,从而破坏了缓存。

Sequence of Events 事件顺序

  1. Browser requests /dashboard 浏览器请求/dashboard
  2. Server increases sentResponse , renders and sends page.ejs to the browser 服务器增加sentResponse ,显示并发送page.ejs到浏览器
  3. Browser receives page.ejs and detects the <script> tag 浏览器接收page.ejs并检测<script>标记
  4. Browser checks if the script URL is in the browser cache 浏览器检查脚本URL是否在浏览器缓存中
    • The sequence ends here if the script URL is found in the cache; 如果在缓存中找到脚本URL,则序列在此结束; clientLoad remains unchanged clientLoad保持不变
  5. Browser requests script from your server 浏览器从您的服务器请求脚本
  6. Server executes get request, increases clientLoad 服务器执行get请求,增加clientLoad

Problem 问题

The "problem" here is that the browser - or any proxy between the browser and your server - will cache the returned script unless you instruct it otherwise. 这里的“问题”是浏览器 - 或浏览器与服务器之间的任何代理 - 将缓存返回的脚本,除非您另外指示它。

Note that caching is actually expected and intended behaviour in most cases. 请注意,在大多数情况下,缓存实际上是预期的和预期的行为。 It's also the browsers's default behaviour. 这也是浏览器的默认行为。

Solution

To instruct the browser (or proxies) to avoid caching the file, you can set 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);
});

This would instruct the browser to never cache the request and always get a new copy, thus increasing clientLoadStart with every request. 这将指示浏览器永远不会缓存请求并始终获取新副本,从而在每次请求时增加clientLoadStart

Another way is " cache busting ", meaning you intentionally change the script's URL, eg by appending a random number as you did above, thus "breaking" the cache key. 另一种方法是“ 缓存清除 ”,这意味着您有意更改脚本的URL,例如通过附加上面的随机数,从而“破坏”缓存键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 服务器发送事件如何向特定客户端发送响应 - How Server Sent Event send response to a specific client 如何在客户端检索由 c# 服务器 Response.Cookies.Append 方法发送的 cookie - How to retrieve cookie on the client side sent by c# server Response.Cookies.Append method Ajax从服务器发送时读取响应 - Ajax reading response from server as it gets sent 服务器向客户端发送消息,但消息未显示在控制台中 - Server sent Message to the client but the Message is not display in the Console 客户端只接收一些服务器发送的事件 - Client receives only some server sent events 最小化JavaScript中客户端/服务器之间发送的数据 - Minimizing data sent between client/server in javascript 服务器端更改客户端发送的日期/时间 - Server side changes date/time sent by client 发送的回复晚于1条回复 - Response sent is 1 response late 动态加载iframe时是否存在“已发送请求-等待响应事件”? - Is there a “request sent - waiting for response event” when dynamically loading an iframe? 如何将Ajax响应作为可下载文件发送到Web浏览器客户端? - How can an Ajax response be sent to the web browser client as a downloadable file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM