Express.js не отправка HTML-файла по запросу post

#node.js #express #http-post #backend #sendfile

#node.js #экспресс #http-post #серверная часть #отправить файл

Вопрос:

Я просто пытаюсь отправить HTML-файл по POST-запросу. Я на 100% уверен, что он работал час назад. С тех пор я не могу понять, почему он внезапно не работает!

Сервер-маршрутизатор:

 const express = require('express');
const router = express.Router();
const cors = require('cors');
const path = require('path');
const auth = require('../middleware/auth.js');

// HOME ROUTE
router.options('/', cors());
router.get('/', cors(), (req, res) => {
   res.status(201).sendFile(path.resolve(__dirname, '../', '../', 'public', 'index.html'));
});
router.post('/', cors(), (req, res) => {
   res.status(201).sendFile(path.resolve(__dirname, '../', '../', 'view', 'manager.html'));
});
  

С сервера нет ошибки.

index.html

 <form method="POST" autocomplete="off">
      <input id="username" type="text" name="username" placeholder="Username" onchange="updateUsername(event)"><br>
      <input id="password" type="password" name="password" placeholder="Password" onchange="updatePassword(event)"><br>
      <button onclick="submitFunc(event)">LOGIN</button>
   </form>

   <script>
      let username_value = document.querySelector('#username').value;
      let password_value = document.querySelector('#password').value;

      function updateUsername(e) {
         username_value = e.target.value;
      }

      function updatePassword(e) {
         password_value = e.target.value;
      }

      async function submitFunc(e) {
         e.preventDefault();
         let response = await fetch('/', {
            headers: { 'Content-Type': 'application/json' },
            method: 'POST',
            body: JSON.stringify({
               username: username_value,
               password: password_value
            })
         });

         console.log(response);
   }
  

Пожалуйста, обратите внимание, что сама логика входа в систему не является проблемой. Я сильно изменил свой код из-за этой проблемы, которая у меня есть.

При отправке POST-запроса в ‘/’ это ответ, который регистрируется в клиентской консоли:
введите описание изображения здесь

Таким образом, сама выборка, похоже, работает просто отлично. Просто новый HTML-файл не заменяет текущий HTML-файл. Как бы мне это исправить?

Комментарии:

1. Пожалуйста, разместите свой код в виде текста, а не в виде снимков экрана. Это позволяет людям копировать / вставлять его в ответы без необходимости перепечатывать все. Это также обеспечивает правильную индексацию для поиска, позволяет читателям экрана видеть его и т. Д… Всегда отправляйте код в виде текста (затем правильно отформатируйте как код здесь) и никогда в виде скриншотов.

2. Кроме того, пожалуйста, покажите клиентский код, который отправляет этот запрос, поскольку кажется, что вы получаете заголовки, но фактически не читаете поток ответов для получения содержимого (как указано в части, которая говорит body: readableStream ).

3. @jfriend00 Отредактировано! Я отправляю данные тела, потому что это в основном простая логика входа в систему. На моем сервере сейчас нет логики аутентификации, потому что я удалил все, чтобы выявить проблему.

Ответ №1:

Вам нужно действительно прочитать ответ. await fetch(...) просто получает заголовки и оставляет там ReadableStream с содержимым, ожидающим, пока вы прочитаете фактическое содержимое с response.json() или response.text() в зависимости от ожидаемого типа данных.

Измените на это:

   async function submitFunc(e) {
     e.preventDefault();
     try {
         let response = await fetch('/', {
            headers: { 'Content-Type': 'application/json' },
            method: 'POST',
            body: JSON.stringify({
               username: username_value,
               password: password_value
            })
         });
         // this assumes the response is text or html, 
         // use response.json() if the response is json
         let data = await response.text()
         console.log(data);
     } catch(e) {
         console.log(e);
         // decide what to do here if there was an error with the fetch() call
     }
 }
  

Вы можете увидеть различные различные методы, доступные для чтения содержимого тела, здесь, в MDN.


Кроме того, если вы делаете запрос с fetch() помощью, ответ с вашего сервера просто вернется к вашему Javascript на вашей веб-странице. Он НЕ будет автоматически отображаться в браузере. Если вы хотите, чтобы он отображался в вашем браузере, то либо разрешите форме post изначально (без Javascript), либо вам придется вручную закодировать свой Javascript для получения ответа, а затем самостоятельно вставить его в содержимое страницы.

Комментарии:

1. Спасибо за ответ. Я пробовал это изначально response.json().then( res => console.log(res) ); . Как мне заменить текущий HTML, если я не хочу использовать встроенную форму?

2. @passionateLearner — Возможно document.body.innerHTML = data . Это предполагает, что data это просто HTML (а не вся структура страницы). Если вам просто нужно нормальное поведение формы, почему вы просто не позволяете браузеру автоматически отправлять форму для вас, а затем автоматически отображать возвращенный контент. Javascript следует использовать, когда вам нужно сделать что-то, что браузер не сделает автоматически за вас. В вашей форме не происходит НИЧЕГО, что требовало бы или даже выгодно публиковать его с помощью Javascript. На самом деле, с Javascript все сложнее.

3. @passionateLearner — Просто добавьте атрибут form action="/" , удалите свой Javascript, и браузер сделает это за вас. По умолчанию браузер отправляет тип содержимого application/x-www-form-urlencoded , поэтому вы захотите, чтобы промежуточное ПО express проанализировало этот тип содержимого для вас, чтобы вы могли автоматически получать параметры формы в своем обработчике экспресс-запросов. Кстати, мне нравится ваше имя пользователя.

4. @passionateLearner — К вашему сведению, если ваш ответ JSON, что именно вы хотите вставить на страницу? Вам нужно будет превратить его в объекты HTML или DOM браузера, прежде чем вы сможете вставить его на страницу. Ваша цель с этим кодом неясна.

5. @passionateLearner — Вы получаете только один ответ и один тип содержимого. Итак, вы отправляете либо HTML, либо JSON в качестве ответа. Если вы отправляете JSON, вы можете поместить HTML в одно из свойств сериализованного объекта JSON, и тогда ваш принимающий код должен знать, как извлечь этот HTML и что-то с ним сделать.