多个AJAX调用期间覆盖了Express请求对象

时间:2017-11-30 13:20:34

标签: node.js ajax express

我们有一个'Express'和基于NodeJS的Web应用程序,它根据在浏览器中生成的图表发送AJAX请求以获取系统数据。客户端代码每3秒调用一次AJAX函数。服务器端代码使用“systeminformation”NPM来获取系统CPU,MEM和其他统计信息,并将其发送回客户端。定时器间隔大于1秒,每件事情都能正常工作。

但是,在将计时器间隔减少到500毫秒时,服务器端REST API崩溃并显示错误“无法在发送后设置标头。”

在分析中,我们发现服务器端代码花费更多时间来完成调用,在此期间,为同一API引发更多AJAX调用,从而调用服务器的相同功能。期间,这些调用有时2个API调用的响应对象变得相同。因此,当一个API发回响应并且另一个API尝试发送响应时,它会收到此错误。我们对此进行了如下验证:

在服务器上的API条目处生成随机ID。因此,每个API调用现在都有一个标识符。然后,API多次调用“systeminformation”以获取所需信息。来自'systeminformation'的数据通过回调返回。当'systeminformation'的最后一次回调返回时,它会将响应发送回客户端。发生错误时我们还打印了布尔'response.headersSent',发现在尝试发送响应之前,以错误结束的调用已将此值设置为 True

在下面的日志中,“start”日志表示在服务器上进入REST API函数。 'cpu','mem'和'fsdata'表示由'systeminformation'模块调用的这些统计数据的回调。 'end'日志表示响应已发送到客户端或控件在catch内的点。响应在'fsdata'回调中发送。因此,理想情况下,当从'systeminformation'调用回调时,'response.headersSent'应设置为false,因为它是作为单个AJAX调用的结果调用的。

对于粗体ID,我们可以看到3个AJAX调用同时运行。因此,现在有3个相同的API调用同时执行。 ID 58142 已成功完成,因为我们可以看到它的“结束”日志。但是,当ID为 79793 的呼叫到达它的'fsData'回调时,它的响应已被发送,如response.headersSent的值为true所示。当呼叫ID 58142 发送响应时,此响应设置为true。因此,ID 58142 79793 的响应对象基本上变得相同,导致此错误。 ID 52972 也是如此。

日志如下:

54817: ----end
44024: ----start
44024: ----cpu
44024: ----mem
44024: ----fsdata
About to send response, response.headersSent: false
44024: ----end
**58142**: ----start
**79793**: ----start
58142: ----cpu
79793: ----cpu
58142: ----mem
79793: ----mem
52972: ----start
52972: ----cpu
**58142**: ----fsdata
About to send response, response.headersSent: false
**58142**: ----end
**79793**: ----fsdata
About to send response, response.headersSent: true
Inside Catch:
About to send response, response.headersSent: true
**79793**: ----end
52972: ----mem
52972: ----fsdata
About to send response, response.headersSent: true
Inside Catch:
About to send response, response.headersSent: true
52972: ----end
41519: ----start
41519: ----cpu
41519: ----mem
41519: ----fsdata
About to send response, response.headersSent: false
41519: ----end
81681: ----start
81681: ----cpu
81681: ----mem
81681: ----fsdata
About to send response, response.headersSent: false
81681: ----end
44642: ----start
44642: ----cpu
44642: ----mem
44642: ----fsdata
About to send response, response.headersSent: false
44642: ----end
94771: ----start
94771: ----cpu
94771: ----mem
94771: ----fsdata

任何人都可以指导我为什么会发生这种情况,这是表达的预期行为吗?

1 个答案:

答案 0 :(得分:0)

AFAIK,这种情况正在发生,因为AJAX每次调用api时都会调用相同的控制器。请尝试使用Promise来获取此代码。每个参数都可以在一个promise中链接,结果可以在最后发送。