【发布时间】:2022-01-23 15:33:12
【问题描述】:
问题:
我使用 ipManager 作为中间件。但由于某种原因,相同的 json 对象被添加到 firestore 两次。此外,还有许多其他行正在重复。
代码:
//imports...
exports.ipManager = (req, res, next) => {
const ip = req.clientIp;
const fullUrl = req.protocol + "://" + req.get("host") + req.originalUrl;
console.log(fullUrl)
if ((ip == "::1") & req.get("host").includes("localhost")) {
console.log(
"[+] ipManager functionalities restricted due to server running in local machine"
);
console.info(`[+] method=GET path=${fullUrl}`);
next();
return;
}
const _URL = req.originalUrl
if (_URL.includes("documentation") || _URL.includes("weather") || _URL=="/") {
console.log(_URL)
} else {
next()
return
}
console.log("IP address " + ip);
axios
.get(`http://ip-api.com/json/${ip}`)
// Show response data
.then((res) => {
const info = res.data;
console.info(JSON.stringify(res.data));
(async () => {
try {
const docRef = await addDoc(collection(db, "req_info_2022.1.22"), {
country: info.country,
countryCode: info.countryCode,
region: info.region,
regionName: info.regionName,
city: info.city,
zip: info.zip,
lat: info.lat,
lon: info.lon,
timezone: info.timezone,
isp: info.isp,
org: info.org,
as: info.as,
ip: info.query,
path: fullUrl,
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
})()
})
.catch((err) => console.log(err));
next();
};
这是控制台日志语句:
注意:请注意,console.logs 重复了两次。因此,两个文档(相同)被保存在 firebase 集合中。
Forec HTTPS 中间件
'use strict';
exports.redirectToHTTPS = (req,res,next) => {
var schema = (req.headers['x-forwarded-proto'] || '').toLowerCase();
if (req.headers.host.indexOf('localhost')<0 && schema!=='https') {
res.redirect('https://' + req.headers.host + req.url);
} else {
next();
}
}
【问题讨论】:
-
啊,可怕的
(async () => { })();。不要这样做。不要这样做。它会导致问题。它是一个异步函数,它返回一个 Promise,而你对这个 Promise 什么都不做。因此,难怪它与您的程序流程或错误处理中的任何其他内容完全脱节。在继续之前,无需等待该承诺完成。如果该承诺拒绝,则不会处理任何错误。 -
我无法关注您的日志,但是这个函数是否只是被多次调用?如果是这样,每次调用
console.log(fullUrl)的输出是什么?而且,你能显示这个函数注册为中间件的代码吗?您需要添加足够多的日志记录,这样您才能了解为什么会调用它。 -
@CuriousLearner 上面的代码中没有任何内容表明此块执行两次的原因。双重执行的原因在这段代码之外,即在调用这段代码的代码中。
-
看起来处理这个 URL
http://weatherdbi.herokuapp.com/data/weather/london的路由调用了这个函数两次。我们无法判断您的服务器是否收到了对该 URL 的两个单独的请求,或者您在服务器中此函数的上游是否有问题导致它两次调用此函数。但是,“两次”问题是您显示的代码的上游。此外,从这段代码中完全不清楚您希望如何在数据库中没有重复项,因为随着时间的推移,同一条路线被多次调用是完全正常的。 -
将此添加为您的第一个中间件:
app.use((req, res, next) =>{console.log("incoming:", req.url); next();});。如果您看到同一 URL 连续记录了两次,则问题出在您的客户端,您必须显示相关的客户端代码,以便我们了解那里发生的情况。如果这只为每个 URL 记录一次,那么您的服务器代码会以某种方式为每个请求调用ipManager两次。
标签: javascript node.js express promise async.js