作者:老娘叫凌凌_523 | 来源:互联网 | 2023-08-29 10:42
我对基于服务器的应用程序非常缺乏经验(而对客户端应用程序的经验只有一点点)。但是,基于许多示例(主要是在Stack Overflow上),我创建了一个基本的NodeJS Web应用程序,该应用程序在本地运行(例如“ heroku本地网络”)时可以正常运行。但是在部署后,除非我插入延迟,否则该应用程序不会接收到POST数据。我确定自己做错了,所以我希望有人可以指出正确的处理方式。我将应用程序精简为基本问题,仍然使用下面的代码显示。
据我所知,简单的网页基本上将JSON数据发布到我的Web应用程序中。 Web应用程序确实收到POST消息。但是在Web应用程序可以收集正在传输的数据之前,Web应用程序似乎已退出。当应用在本地运行时,数据不会丢失(当我在Google Cloud上部署早期版本时,数据也不会丢失)。但是,当部署在Heroku(免费版)上时,损失确实会发生。
其他几种语言的经验让我感到困惑,为什么NodeJS应用程序在收到任何消息之前并不总是退出,因为该应用程序中没有代码来延迟退出(例如消息泵或等待退出信号) 。当它起作用时,我耸了耸肩,认为游戏中有一些魔术,我以后会学习。但实际上,我看到的失败对我来说更有意义。
无论如何,正是这种怀疑导致我增加了延迟(下面显示的行带有// ***的注释)。由此,我能够确定数据已经到位,但没有被延迟收集。
下面是主要代码文件。在这些记录下,有一些日志显示了添加延迟前后的本地和远程行为。
任何帮助表示赞赏。
index.html:
server.js:
const http = require('http');
const fs = require('fs');
var server = http.createServer(
function (req,res) {
console.log(`req.url: ${req.url}\n`);
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data',function (data) {
body += data;
});
req.on('end',function (data) {
console.log(JSON.parse(body));
});
res.writeHead(200,{'Content-Type': 'text/html'});
res.end('post received');
console.log("Sleeping 5 seconds"); // ***
setTimeout(function(){ // ***
console.log("POST end");
},5000); // ***
} else {
console.log("GET");
fs.readFile('./' + req.url,function(err,data) {
if (!err) {
var dotoffset = req.url.lastIndexOf('.');
var mimetype = dotoffset == -1
? 'text/plain'
: {
'.html' : 'text/html','.ico' : 'image/x-icon','.jpg' : 'image/jpeg','.png' : 'image/png','.gif' : 'image/gif','.css' : 'text/css','.js' : 'text/Javascript'
}[ req.url.substr(dotoffset) ];
res.setHeader('Content-type',mimetype);
res.end(data);
} else {
console.log ('file not found: ' + req.url);
res.writeHead(404,"Not Found");
res.end();
}
});
}
}
);
const PORT = process.env.PORT || 5000;
server.listen(PORT,() => {
console.log(`Server is running (port: ${PORT})...`);
});
console.log("FILE end");
添加延迟前本地:
10:24:00 PM web.1 | FILE end
10:24:00 PM web.1 | Server is running (port: 5000)...
10:24:14 PM web.1 | req.url: /index.html
10:24:14 PM web.1 | GET
10:24:18 PM web.1 | req.url: /server.js
10:24:18 PM web.1 | POST
10:24:18 PM web.1 | POST end
10:24:18 PM web.1 | { fruit: 'apple',size: 'medium',color: 'red' }
在添加延迟之前部署:
2019-12-18T04:31:52.835329+00:00 app[web.1]: FILE end
2019-12-18T04:31:52.837439+00:00 app[web.1]: Server is running (port: 17378)...
2019-12-18T04:32:14.929250+00:00 heroku[router]: at=info method=GET path="/index.html" host=****.herokuapp.com request_id=**** fwd="*.*.*.*" dyno=web.1 cOnnect=0ms service=9ms status=200 bytes=1233 protocol=https
2019-12-18T04:32:14.925381+00:00 app[web.1]: req.url: /index.html
2019-12-18T04:32:14.925407+00:00 app[web.1]:
2019-12-18T04:32:14.925509+00:00 app[web.1]: GET
2019-12-18T04:32:25.004774+00:00 app[web.1]: req.url: /server.js
2019-12-18T04:32:25.004809+00:00 app[web.1]:
2019-12-18T04:32:25.004964+00:00 app[web.1]: POST
2019-12-18T04:32:25.006023+00:00 app[web.1]: POST end
添加延迟后的本地:
10:48:04 PM web.1 | FILE end
10:48:04 PM web.1 | Server is running (port: 5000)...
10:48:08 PM web.1 | req.url: /index.html
10:48:08 PM web.1 | GET
10:48:12 PM web.1 | req.url: /server.js
10:48:12 PM web.1 | POST
10:48:12 PM web.1 | Sleeping 5 seconds
10:48:12 PM web.1 | { fruit: 'apple',color: 'red' }
10:48:17 PM web.1 | POST end
在添加延迟后部署:
2019-12-18T04:51:50.925802+00:00 app[web.1]: req.url: /index.html
2019-12-18T04:51:50.925831+00:00 app[web.1]:
2019-12-18T04:51:50.925944+00:00 app[web.1]: GET
2019-12-18T04:51:56.071684+00:00 heroku[router]: at=info method=POST path="/server.js" host=****.herokuapp.com request_id=**** fwd="*.*.*.*" dyno=web.1 cOnnect=0ms service=6ms status=200 bytes=151 protocol=https
2019-12-18T04:51:56.064644+00:00 app[web.1]: req.url: /server.js
2019-12-18T04:51:56.064659+00:00 app[web.1]:
2019-12-18T04:51:56.068033+00:00 app[web.1]: POST
2019-12-18T04:51:56.069013+00:00 app[web.1]: Sleeping 5 seconds
2019-12-18T04:51:56.075197+00:00 app[web.1]: { fruit: 'apple',color: 'red' }
2019-12-18T04:52:01.073243+00:00 app[web.1]: POST end
以防以后有人遇到此问题,我对此没有任何反馈,也无法真正找到合理的解决方法。 (我尝试了Promise和其他一些临时信号。)因此,我知道使用Express作为我的服务器,从而在全球范围内成功部署了这一点。考虑到极其简单的数据传输,切换是微不足道的,并且工作正常。 (我打算深入研究Express源,以了解他们如何处理它,但似乎将它包含在我的NodeJS应用程序中会导入200多个其他软件包,因此,实在是不鼓励使用。)