XMLHTTPRequest在本地主机上的服务器上不起作用

时间:2019-01-02 16:09:57

标签: node.js server cors xmlhttprequest localhost

我正在开发一个node.js RESTful服务器,用于与Raspbian一起在RPI上用于家庭用途,并且为了进行测试,我创建了一个测试HTML页面,该页面可以制作各种{{1} }。

开发时,我在XMLHttpRequest上运行的开发机(台式机,而不是RPI)上使用测试nodemon服务器,并在测试HTML页面 >指向它。 每当我准备提交更改时,就将它们推送到服务器(RPI),甚至是测试页面。它应该连接到本地主机上的服务器。

每当我在服务器上测试页面时,就会发生一些奇怪的事情:localhost:4000方法无法识别localhost,但是如果我输入地址网络中的服务器计算机(不是127.0.0.1,而是192.168.1.X),就可以使用。

命令XMLHttpRequest.open显示节点服务器正在侦听端口netstat -vltn,我启用了CORS,我已经尝试写4000而不是127.0.0.1 ,甚至修改了app.listen函数来监听localhost,如下所示:

0.0.0.0

但是,从服务器上托管的测试页到localhost:4000的每个请求都无效

我的问题是,如果我需要在服务器上推送测试页,则需要每次手动更改app.listen(port, '0.0.0.0', function () { console.log('RESTful API server started on: ' + port); }); 的IP地址,而不仅仅是保留本地主机。有没有办法启用本地主机的使用?

编辑:我正在添加一些客户端代码来充实问题。

testpage.html (在开发机器和RPI上均应工作的那个)

XMLHttpRequest

server.js (使用<html> <head> <script type="text/javascript"> function sendData() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { // Typical action to be performed when the document is ready: document.getElementById("demo").innerHTML = xhttp.responseText; } }; xhttp.onerror = function(e) { console.log('error', e); }; xhttp.open("POST", "http://127.0.0.1:4000/auth/loginTest", true); xhttp.setRequestHeader("Content-Type", "application/json"); //I've omitted the part where I'm prepping a json with username/password data xhttp.send(jsonString); } </script> </head> <!--I'm skipping the rest of the code as there's only a div that catches the json info sent by the server --> 在RPI上启动的服务器)

node server.js

2 个答案:

答案 0 :(得分:1)

尝试更改此代码:

app.listen(port, '0.0.0.0', function () {
  console.log('RESTful API server started on: ' + port);
});

对此:

app.listen(port, function () {
  console.log('RESTful API server started on: ' + port);
});

这将使您的应用程序同时侦听IPv4和IPv6。 localhost可能解析为IPv6地址,而您的代码仅在侦听IPv4地址。我知道MAC为localhost使用IPv6。

要尝试的另一件事是停止在客户端上使用单词localhost,然后使用127.0.0.1,看看有什么区别。

更新:

下面是我从您的服务器生成的服务器代码,它似乎可以正常工作:

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const port = process.env.PORT || 4000;

function sendPage(req, res, next) {
  console.log('sending page');
  res.send(`<html>
<head>
  <script>
  function sendData() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {
        // Typical action to be performed when the document is ready:
        document.getElementById("demo").innerHTML = xhttp.responseText;
      }
    };

    xhttp.onerror = function(e) {
      console.log('error', e);
    };

    xhttp.open("POST", "http://127.0.0.1:4000/auth/loginTest", true);
    xhttp.setRequestHeader("Content-Type", "application/json");
    //I've omitted the part where I'm prepping a json with username/password data
    xhttp.send('{"user":"dog","pw":"woof"}');
  }
  </script>
</head>
<body onload="sendData()">
<h1>Test page</h1>
<div id="demo"></div>
<hr/>
</body>
</html>`);
}

function auth() {
  console.log('auth called');
  var router = express.Router();

  router.post('/loginTest', (req, res, next) => {
    console.log('auth was called');
    console.log(req.body);
    res.json({error: false, data:'hi'});
  });

  return router;
}

const app = express();
app.use(bodyParser.json({ type: 'application/json' }));
app.options('*', cors());
app.use(cors());
app.get('/', sendPage);
app.use('/auth', auth());

process
  .on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
    process.exit(1);
  });

app.listen(port, function () {
  console.log('RESTful API server started on: ' + port);
});
  

如果这与您的代码不太相符,请告诉我我错了。

答案 1 :(得分:0)

很抱歉延迟。我忘了发布解决方案了。

我的方法永远都行不通,因为加载测试页时,它将尝试在http://localhost:4000上执行脚本,如果从服务器正在侦听的计算机上加载页面,则可以这样做,但是显然如果它在另一台计算机上将无法工作(因此出现ERR_CONNECTION_REFUSED错误)。 如果我从服务器计算机加载此页面,它将尝试在计算机上执行脚本,这是无效的请求。 因此,我已通过在请求中将http://localhost:4000替换为机器的实际IP(例如http://Write.Real.Address.Here:4000)来解决了该问题。