Nodejs Express服务器无法响应HTTP POST请求:OpenShift

3

在我的第一次使用Node的经验中,我已经在Openshift上托管了一个Nodejs服务器,希望不久将其用于Android应用程序服务器。目前,我正在尝试获取一个简单的express应用程序,它将响应HTTP POST请求。这是该服务器的代码; 我已经尽可能地简化它,并且它可以很好地响应GET请求,但POST回调似乎从未执行:

#!/bin/env node
var http = require('http');
var bodyParser = require('body-parser');

var express = require('express');
var app = express();

app.use(bodyParser.urlencoded({ extended: false }));

app.post('/', function (req, res) {

    res.end("Post successful.");
});

app.get('/', function (req, res) {
    res.end("App listening on port: " + process.env.OPENSHIFT_NODEJS_PORT);
});

http.createServer(app).listen(process.env.OPENSHIFT_NODEJS_PORT, 
    process.env.OPENSHIFT_NODEJS_IP, function() {
        console.log("Server started on %s.", Date(Date.now()));
});

这是我一直在使用的Node脚本来测试响应。我不认为它是问题所在,因为我也尝试过在Java中进行POST和使用HTML表单,但似乎都不起作用:

var http = require('http');

var data = JSON.stringify({
    'message' : 'hello'
});

var options = {
    host: 'xx-xx.rhcloud.com',
    port: '8080',
    path: '/',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': data.length
    }
};

var request = http.request(options, function(res) {

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        console.log('Response: ' + chunk);
    });

    res.on('end', function(err) {
        console.log("Post successful");
    });
});

request.write(data);
request.end();

我可以在本地运行服务器时执行回调,但只有在那时硬编码端口和IP才行。一旦我启动服务器,它会响应GET请求并返回端口号,我假设它始终是8080,但即使在主机上将端口硬编码为8080也无法解决问题。尽管如此,我认为这是一个端口问题,因为当我尝试发送请求时,我的发布脚本和浏览器都挂起,而不是抛出连接错误。当然,我是个完全的新手,很可能忽视了一个简单但关键的元素。提前致谢。

我已经测试了你的代码,如果你输入本地主机和一些端口,它可以正常工作,所以我猜你在配置方面遇到了麻烦? - Doron Sinai
1
我也可以在本地主机上正常运行。问题出现在我尝试向托管在OpenShift上的服务器POST时。 - Jimmy Pruitt
2个回答

1
这可能反映了我对Web技术的经验不足,但我发现问题所在:当尝试对特定端口进行POST操作时,服务器无响应。然而,如果我从我的POST脚本中完全删除端口声明,则它可以正常工作。有人能解释一下为什么吗?

2
您的应用程序由OpenShift在端口80(默认HTTP端口)提供服务。通过从URL中删除端口,实际上是在URL中指定了端口80,这就是为什么它现在可以工作的原因。看起来您混淆了OpenShift要求您的应用程序绑定到的内部端口(通常为8080)与它实际提供服务的端口,后者始终是OpenShift上的端口80。 - Mark B
这就解释了为什么浏览器在这种情况下可以工作,但这是否意味着所有的POST请求默认都发送到端口80? - Jimmy Pruitt
2
是的,HTTP默认端口为80。如果您没有指定端口(无论是GET还是POST请求),它将默认使用端口80。同样,HTTPS默认端口为443。如果您指定了“http://”而没有指定端口,则将使用端口80。如果您指定了“https://”而没有指定端口,则将使用端口443。在OpenShift上,HTTP和HTTPS流量都路由到服务器上的端口8080。 - Mark B
@mbaird,如果您熟悉Node的话,我还有一个问题。我正在使用OpenShift提供的免费套餐托管此服务器,该套餐允许3个Web应用程序而无需付款。为了提高性能,我想我会有多个专用于一项任务的服务器,例如登录、发送消息和发送通知。我需要创建单独的HTTP服务器来实现这一点吗?如果是这样,每个服务器都会计算为一个单独的Web应用程序吗? - Jimmy Pruitt
1
这在OpenShift上行不通。除非你预计有大量的流量,否则这也可能过度设计。在OpenShift上,您可以通过在多个服务器上运行相同的代码来扩展应用程序。如果要在不同的服务器上运行不同的代码,则需要在OpenShift上创建全新的应用程序,但是它们将无法共享数据库。听起来您只需要为每个任务在应用程序中创建单独的页面或端点。然后,如果需要更好的性能,您可以将负载分布到多个服务器上。 - Mark B

0

我的回答可能有点晚,但是我在这里解决了同样的问题,也许这会帮助其他人。

假设你的应用程序具有以下公共URL:

http://xyz-dercetech.rhcloud.com/api/authenticate

它变得无响应。

-> rhcloud.com有自己的内部路由,所以process.env.OPENSHIFT_NODEJS_*在他们自己的服务器之外是没有用的。您的NodeJS应用程序绑定到一个内部IP和端口,但该IP不是公共的。

使用上述公共URI,您将享受GET请求无缝传递。但正如您所说,POST会失败。

只需在您的URI中添加https端口:

http://xyz-dercetech.rhcloud.com:443/api/authenticate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接