当客户端不在同一 IP 上时,无法通过客户端调用节点服务器

Posted

技术标签:

【中文标题】当客户端不在同一 IP 上时,无法通过客户端调用节点服务器【英文标题】:Cannot call node server via client when client is not on same IP 【发布时间】:2015-01-21 15:58:20 【问题描述】:

我有一个运行 express js 的节点 js 服务器,并使用 ionic-framework (cordova/phonegap) 创建了一个前端客户端。在托管服务器的同一台计算机上运行客户端时,我能够成功地对我的服务器进行 ajax 调用并接收正确的回复,因为它们在同一 IP 上运行。

当我尝试在与服务器不同的 IP 上运行客户端时,问题就出现了。我已经阅读了在服务器端设置 cors 的内容。我的设置与此处的设置几乎相同: Allow CORS REST request to a Express/Node.js application on Heroku

这是我的 cors 设置:

var express = require('express');
var compress = require('compression');
var bodyParser = require('body-parser');

var app = express();
var cors = function(req, res, next) 
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    appLogger.info('testing');
    if ('OPTIONS' == req.method) 
        res.send(200);
    
    else 
        next();
    
;
app.use(cors);
app.use(compress());
app.use(bodyParser.urlencoded( extended: true ));
app.use(bodyParser.json());
app.use(function(err, req, res, next)  // Handle errors...
    res.send(500, err.toString());
    appLogger.error(err.stack);
);

在主机上运行 ui 时,我在控制台中看到“正在测试”,所以我知道它正在第一次通过那里。

我还在 config.xml 中检查了我的 ui 应用程序的白名单:

<access origin="*" subdomains="true"/>

我尝试了以下 ajax 查询:

$.ajax(
    type: "POST",
    url: "http://hostIPAddress:7777/login",
    crossDomain: true,
    async: true,    
    data: 
        email: $scope.accountData.email,
        password: $scope.accountData.password
    ,
    dataType: "json",
    timeout: 5000
)
.done(function(data, textStatus, jqXHR) 
    var json = data;
    alert(JSON.stringify(json));
    console.log(JSON.stringify(json));
)
.fail(function(jqXHR, textStatus, errorThrown) 
    alert('Error logging in: ' + errorThrown);
    alert(JSON.stringify(jqXHR));
);

我也尝试过使用 Angular JS 的 $http

$http(
    method : 'post',
    url: 'http://hostIPAddress:7777/login',
    data: data,
    timeout: 5000
)
.success(function(data, status, headers, config) 
    alert('Success');
)
.error(function(data, status, headers, config) 
    alert('Fail: ' + JSON.stringify(data));
    alert('Status: ' + JSON.stringify(status));
    alert('Headers: ' + JSON.stringify(headers));
    alert('Config: ' + JSON.stringify(config));
);

同样,当客户端与节点服务器在同一台计算机上运行时,这一切(常规的 ajax 调用和 angular js 的 $http 方法)都有效。我也尝试过使用 / 不使用 crossDomain: true 的 ajax 调用,但无济于事。

其他信息: 当我运行 ajax 后调用时,调用失败时我没有得到任何相关信息。一切都是空的或空白的。 $http 调用返回 404 状态,就像找不到主机一样。当服务器未运行时,我能够 ping 与主机关联的 IP,但是当我在服务器运行时 ping IP 时,ping 返回超时。

有人对可能发生的事情有任何想法吗?如果我能提供更多有用的信息,请告诉我。

提前致谢!

更新 - 2014 年 11 月 23 日晚上 11:08

这是我的客户端 ui 发送的标头:

Request URL:http://myserverip:7777/login
Request Headers
Provisional headers are shown
Accept:application/json, text/javascript, */*; q=0.01
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Origin:http://localhost:8100
Referer:http://localhost:8100/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko)             Chrome/39.0.2171.65 Safari/537.36
Form Data
email:testemail@gmail.com
password:password1

更新 - 2014 年 11 月 24 日晚上 11:27

我能够通过 curl 从我的手机成功运行 http 请求到服务器。所以我知道我的服务器正在响应外部请求。发生问题的是离子客户端。

更新 - 2014 年 11 月 26 日上午 9:18

我尝试从一台计算机的浏览器导航到另一台计算机的 url,但它超时。我试过了,chrome、safari 和 IE。我从两台不同的计算机上尝试了 curl,但它找不到主机。我可以从我的 iPhone 导航到 url,它会返回正确的响应,但是如果我从我的 android 手机上做同样的事情,它就找不到主机。所以无论出于什么原因,我只能用我的 iPhone 找到主机。

【问题讨论】:

【参考方案1】:

确保您的服务器知道如何响应“OPTION”请求。如果您的服务器应用程序没有对选项请求返回正确的响应,那么您的浏览器将无法连接到远程服务。

【讨论】:

对不起,我忘了提到我也从帖子中提供的网址尝试过。 if ('OPTIONS' == req.method) res.send(200); 其他 下一个(); 我刚刚在我的 cors 对象中重新测试了它,它的行为方式相同。我认为第一次通过至少会登录控制台“测试”,无论客户端是否认为它可以连接。 我很想看看您的网络活动是什么样的,并检查标题是否正确。在浏览器设置中,您可以打开监控以确保您的标头对于请求和预检是正确的。 将请求的标头添加到帖子中。【参考方案2】:

我的环境出了点问题。我在 openshift 上托管了我的服务器,它运行良好。

【讨论】:

以上是关于当客户端不在同一 IP 上时,无法通过客户端调用节点服务器的主要内容,如果未能解决你的问题,请参考以下文章

客户端不在 NT 域上时的 Microsoft Office Communicator 2007

当邮件服务器不在网络主机上时发送邮件和 MX 记录

因客户机IP与服务器IP不在同一网段导致无盘客户机开机卡tftp,提示:PXE-E11: ARP timeout

链接服务器在同一服务器上时双跳,差异服务器上的客户端?

Nacos跨服务器调用服务报错

当用户在不同的网络上时Webrtc没有视频