Nodejs Express 不需要的行为:让两个不同的 http 请求以唯一的答案回复
Nodejs Express unwanted behavior: getting two different http requests replied in a unique answer
代码如下:
FILE: server.js
var express = require('express'),
app = express(),
useragent = require('express-useragent'),
compression = require('compression'),
vhost = require('vhost');
app.use(vhost("blabla.com", 'app.js'));
app.disable('x-powered-by');
app.use(compression());
app.use(useragent.express());
app.listen(80);
FILE app.js
var useragent = require('express-useragent'),
express = require('express'),
sessao = require('express-session'),
armazenamento_ficheiros = require('session-file-store')(sessao),
compression = require('compression'),
app = express(),
favicon = require('serve-favicon');
global.uuid = require('uuid');
app.all('/u/my.json', function (req, res) {
var body = '';
p.on('data', function (d) {
body += d;
});
p.on('end', function () {
var g = require('./gateway');
g.e(body,res);
}, 'utf-8');
});
module.exports = app;
FILE:gateway.js
module.exports = {
e: function (body,res) {
//connects to database using data in body and send results to client....
res.header("Cache-Control", "no-cache, no-store, must-revalidate");
res.header("Pragma", "no-cache");
res.header("Expires", 0);
res.header('Last-Modified', (new Date()).toUTCString());
res.header("Content-type", "application/json; charset=utf-8");
res.send(JSON.stringify({"a":1}));
}
};
问题在于,有时客户端会随机发出两个 http 请求,并且都以唯一的答案进行回复,而不是每个 http 请求都获得相应的回复。问题似乎是当其中一个 http 请求向数据库发出请求(造成获取答案的延迟)并在另一个请求中得到答复时。由于我发送了 headers,它给出了错误。
我检查每个 http 请求是否加载并执行了 gateway.js 文件,但我不明白为什么它们会混在一起。我的代码有什么问题?任何帮助将不胜感激。谢谢。
是的,当使用异步代码时,您不能将唯一函数分配给全局变量,然后期望正确的异步操作从全局变量中获取正确的唯一函数。您的代码不会 运行 同步,因此您无法将某些内容放入共享变量中,然后知道正确的内容会在正确的时间出现并且不会被覆盖。那只是一个永远不会可靠的糟糕设计。
在 Express 架构的服务器中,为每个请求创建了一个唯一的 request
和 response
对象,并且至少通常传递响应对象直到响应完成(因为需要它)做出回应)。如果您需要一个地方来存储特定于此特定请求的数据,那么您可以将自己的自定义 属性 添加到 response
或 request
对象,您将避免两个问题由于异步操作,请求 运行在重叠的时间范围内可能会破坏彼此的状态。
我没有完全遵循您的代码,但由于看起来您正在传递 response
对象,您可以在响应对象上放置一个独特的函数,然后从那里调用它。但更好的办法是将您的独特数据与响应对象一起传递,而不是每次都创建一个新函数。
我看到的其他问题:
您通过多次 var app = express();
创建了多个 app
对象。这很少是正确的实施。您通常只想创建一个 app
对象,并且应该是您调用 app.listen(80)
的对象。
你的单字母变量名使你的代码更难让那些还不知道你的代码的人立即理解它。请使用描述性和有意义的变量名称。这不是试图节省几个字节的地方。
global.make_reply()
的第一个参数应该是什么?当您定义该函数时,您使它看起来像一个具有 .header()
和 .send()
方法的响应对象。但是,当您在 gateway.js
中调用它时,您会传递一个字符串作为第一个参数。在您编写代码时,我不明白这可能如何工作。
代码如下:
FILE: server.js
var express = require('express'),
app = express(),
useragent = require('express-useragent'),
compression = require('compression'),
vhost = require('vhost');
app.use(vhost("blabla.com", 'app.js'));
app.disable('x-powered-by');
app.use(compression());
app.use(useragent.express());
app.listen(80);
FILE app.js
var useragent = require('express-useragent'),
express = require('express'),
sessao = require('express-session'),
armazenamento_ficheiros = require('session-file-store')(sessao),
compression = require('compression'),
app = express(),
favicon = require('serve-favicon');
global.uuid = require('uuid');
app.all('/u/my.json', function (req, res) {
var body = '';
p.on('data', function (d) {
body += d;
});
p.on('end', function () {
var g = require('./gateway');
g.e(body,res);
}, 'utf-8');
});
module.exports = app;
FILE:gateway.js
module.exports = {
e: function (body,res) {
//connects to database using data in body and send results to client....
res.header("Cache-Control", "no-cache, no-store, must-revalidate");
res.header("Pragma", "no-cache");
res.header("Expires", 0);
res.header('Last-Modified', (new Date()).toUTCString());
res.header("Content-type", "application/json; charset=utf-8");
res.send(JSON.stringify({"a":1}));
}
};
问题在于,有时客户端会随机发出两个 http 请求,并且都以唯一的答案进行回复,而不是每个 http 请求都获得相应的回复。问题似乎是当其中一个 http 请求向数据库发出请求(造成获取答案的延迟)并在另一个请求中得到答复时。由于我发送了 headers,它给出了错误。
我检查每个 http 请求是否加载并执行了 gateway.js 文件,但我不明白为什么它们会混在一起。我的代码有什么问题?任何帮助将不胜感激。谢谢。
是的,当使用异步代码时,您不能将唯一函数分配给全局变量,然后期望正确的异步操作从全局变量中获取正确的唯一函数。您的代码不会 运行 同步,因此您无法将某些内容放入共享变量中,然后知道正确的内容会在正确的时间出现并且不会被覆盖。那只是一个永远不会可靠的糟糕设计。
在 Express 架构的服务器中,为每个请求创建了一个唯一的 request
和 response
对象,并且至少通常传递响应对象直到响应完成(因为需要它)做出回应)。如果您需要一个地方来存储特定于此特定请求的数据,那么您可以将自己的自定义 属性 添加到 response
或 request
对象,您将避免两个问题由于异步操作,请求 运行在重叠的时间范围内可能会破坏彼此的状态。
我没有完全遵循您的代码,但由于看起来您正在传递 response
对象,您可以在响应对象上放置一个独特的函数,然后从那里调用它。但更好的办法是将您的独特数据与响应对象一起传递,而不是每次都创建一个新函数。
我看到的其他问题:
您通过多次
var app = express();
创建了多个app
对象。这很少是正确的实施。您通常只想创建一个app
对象,并且应该是您调用app.listen(80)
的对象。你的单字母变量名使你的代码更难让那些还不知道你的代码的人立即理解它。请使用描述性和有意义的变量名称。这不是试图节省几个字节的地方。
global.make_reply()
的第一个参数应该是什么?当您定义该函数时,您使它看起来像一个具有.header()
和.send()
方法的响应对象。但是,当您在gateway.js
中调用它时,您会传递一个字符串作为第一个参数。在您编写代码时,我不明白这可能如何工作。