XMLHTTPRequest не работает на сервере на локальном хосте - PullRequest
0 голосов
/ 02 января 2019

Я разрабатываю node.js RESTful-сервер для домашнего использования на RPI с Raspbian, а для тестирования я создал тестовую HTML-страницу , которая делает различные XMLHttpRequest с.

При разработке я использую тестовый сервер nodemon на своем компьютере разработчика (настольный компьютер, а не RPI), работающий на localhost:4000, и тестовая HTML-страница указывает на него. Всякий раз, когда я готов принять изменения, я отправляю их на сервер (RPI), даже на тестовую страницу. Он должен подключиться к серверу на локальном хосте.

Что-то странное происходит, когда я проверяю страницу на сервере : localhost не распознается в методе XMLHttpRequest.open, но если я введу адрес компьютера сервера в сеть (не 127.0.0.1, а, например, 192.168.1.X), работает.

Команда netstat -vltn показывает, что сервер узла прослушивает порт 4000, я включил CORS, я уже пытался написать 127.0.0.1 вместо localhost, и я даже изменил Функция app.listen для прослушивания 0.0.0.0, например:

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

но все же каждый запрос от тестовой страницы, размещенной на сервере, к localhost: 4000 не работает .

Моя проблема в том, что, если мне нужно нажать на тестовую страницу на сервере, мне нужно каждый раз вручную менять IP-адрес для XMLHttpRequest вместо того, чтобы просто хранить localhost. Есть ли способ включить использование localhost?

РЕДАКТИРОВАТЬ : Я добавляю некоторый клиентский код для уточнения проблемы.

testpage.html (тот, который должен работать как на компьютере разработчика, так и на RPI)

<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 -->

server.js (тот, который запускается на RPI с node server.js)

var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var port = process.env.PORT || 4000;
var auth = require(/*path to Auth middleware*/);

var app = express();
app.use(bodyParser.json({ type: 'application/json' }));

app.options('*', cors());
app.use(cors());

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);
});

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Извините за задержку.Я забыл опубликовать решение.

Мой подход никогда не сработает, потому что при загрузке тестовой страницы он попытается выполнить скрипт на http://localhost:4000, что нормально, если страница загружена с компьютера.где сервер слушает, но, очевидно, не будет работать, если он находится на другой машине (отсюда ошибка ERR_CONNECTION_REFUSED).Если я загружу эту страницу с сервера, она попытается выполнить скрипт на моем компьютере, что является неверным запросом.Так что я решил это, просто заменив http://localhost:4000 в запросе фактическим IP-адресом машины, например http://Write.Real.Address.Here:4000.

0 голосов
/ 02 января 2019

Попробуйте изменить этот код:

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 использует IPv6 для localhost.

Другая вещь, которую нужно попробовать, - прекратить использовать слово localhost на клиенте и использовать 127.0.0.1 и посмотреть, имеет ли это какое-то значение.

UPDATE:

Ниже приведен код моего сервера, который я сгенерировал из вашего, и, похоже, он работает:

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);
});

Если это не соответствует вашему коду, дайте мне знать, где я ошибся.

...