【问题标题】:Node.js API MongoDB request only working on localhostNode.js API MongoDB 请求仅适用于本地主机
【发布时间】:2016-06-01 18:28:28
【问题描述】:

我正在开发一个应用程序,我正在从一个运行在 Node.js 上的 API 请求数据,该 API 查询一个 MongoDB

当我从 localhost 但不是从外部源访问应用程序时,它会运行。由于我使用移动设备访问服务器,因此很难说出错误是什么。 当我尝试从其他地方访问它时,我可以看到主页,但看不到来自 APP 的数据

起初我什至无法从 localhost 获取它,所以我发现该代码及其在 localhost 上工作。

app.all('/*', function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

是的,这并不安全。

编辑

我希望能够从任何地方连接到我的电脑并使用该应用程序。

Node.js服务器如下;

var express = require('express');
var app = express(); 
 app.use(express.static(__dirname + '/www'));
app.listen(80);

我的应用程序

   var express = require('express');
    var MongoClient = require('mongodb').MongoClient;
    var assert = require('assert');
    var ObjectId = require('mongodb').ObjectID;
    var url = 'mongodb://localhost:27017/site'; 
    var app = express();

//This was added because I was getting cross domain error even on local network
        app.all('/*', function (req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        next();
        });
   // NOT SECURE

    var findIco = function(db, callback) {
        db.collection('footIco').find().toArray(function(err, docs) {
            if (err) return callback(err, null);
            return callback(null, docs);
        });
    }

app.get('/icons', function(req, res){
  MongoClient.connect(url, function(err, db) {
    if(err) {
      console.log(err);
      return res.status(500).send(err);
   }
    findIco(db, function(err, icons) {
        if(err){
          res.status(500).json(err);
        }
        else{
            if(!icons){
              res.status(204).send();
              }
              else{
                  res.json(icons);
                  }
               db.close();
               return;
            }
        });  
    });
  });

JavaScript;

var app = angular.module('app', ["ngSanitize"]);
app.controller('footIconCtrl', function($scope, $http) {

$http({
  method: 'GET',
  url: 'http://localhost:8080/icons'  // <--- Will only work locally
  //url: 'http://my.ip.addr.:8080/icons'  // <--- Will only work extrernally
})
  .then(function(icons) {
  console.log(icons);
    $scope.icons = icons.data;
  })
  .catch(function(errRes) {
    // Handle errRess
  });
});

我也试过了;

app.controller('footIconCtrl', function($scope, $http) {

var url = 'http://my.ip.add.res:8080/icons&callback=JSON_CALLBACK';

 $http.jsonp(url).success(function(data) {
    //what do I do here?
     $scope.icons=data;
});
});

得到相同的结果!

编辑#2

刚刚发现是 Mongo 拒绝连接。我已将所有 ip 从 localhost 更改为我的真实 IP,但在 Node.js 控制台中出现此错误

{ [MongoError: connect ECONNREFUSED 111.222.333.444:27017]
  name: 'MongoError',
  message: 'connect ECONNREFUSED 111.222.333.444:27017' }

当然,这不是我的真实 IP,但我不想今晚被黑!而且我不明白为什么只有在提供 localhost 作为地址时它才能在本地工作,而另一方面,如果我提供我的 WAN IP,它只会在外部工作。

【问题讨论】:

  • 您必须转发您的端口或连接到与您尝试连接的设备相同的本地网络。此外,从您的外部设备请求http://localhost:8080localhost == 127.0.0.1 一样没有意义,这意味着这台计算机/设备。你的帖子不是很清楚,但据我了解,当这些标题出现时你能够连接?如果是这种情况,这意味着 CORS (Access-Control-Allow-Origin) 必须启用 * 才能请求该资源。
  • 是的,我需要这些标题才能使应用程序正常工作。所以我将不得不使用完整的地址。试试看,谢谢!
  • 如果你在开发时需要这些头文件,我建议你把它们放在一个 if 子句中。例如:if(process.env.NODE_ENV !== 'production') { // add headers... }。然后,当您将脚本部署到生产环境时,您将执行 export NODE_ENV=production 然后启动您的应用程序并且不会添加这些标头(强烈建议NODE_ENV 设置为 production部署时)

标签: node.js mongodb


【解决方案1】:

您可以尝试两种解决方案:

  1. 通过设置Access-Control-Allow-Origin: * 使用您当前的解决方案。这将违反每个现代浏览器重要的内置 CORS 政策。您的系统将不会受到保护,因为它向全世界开放了所有 API。
  2. 更改 node.js API 的实现以支持/icons API的跨域请求,并且仅接受来自某些 IP 地址的 GET 请求。在角度部分,使用$http.jsonp 调用api。您的系统将更加安全。请参阅this SO post 了解jsonp 在 node.js 上的实现。

【讨论】:

  • 我已经添加了我的完整代码。我是这个节点交易的新手,所以我不确定如何实现安全且有效的代码。
  • 好吧。所以只需按照 SO 链接使用 res.jsonp 和 $http.jsonp。
  • app.controller('footIconCtrl', function($scope, $http) { var url = 'my.ip.adr.ess:8080/icons&callback=JSON_CALLBACK'; $http.jsonp(url).success(function(data) { $范围图标=数据;});});我得到了完全相同的结果。
【解决方案2】:

确保您的节点服务器正在您的计算机上运行 internalIp - 这可能是 192.168.0.10,也可能在您的 external source 上(我假设这是手机上的浏览器),确保您引用的是192.168.0.10:PORT_NUMBER_HERE(您的内部 IP,检查此 http://www.computerhope.com/jargon/i/internip.htm)在您的 html、php 或您使用的任何语言中。

如果您尝试从App 访问API 调用,请确保源代码中的任何url's 都引用了您的internal ip。还要确保您运行API 呼叫的设备连接到与节点服务器相同的互联网网络。

希望这会有所帮助,因为您提供的信息很少,说明您尝试从何处访问 api 呼叫。

【讨论】:

    猜你喜欢
    • 2023-02-03
    • 2018-11-16
    • 2017-02-25
    • 2023-04-05
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    相关资源
    最近更新 更多