Почему req.body пуст при публикации формы в quiz.ejs

приложение.js

const express = require('express');
const mongoose = require('mongoose');
const path=require('path');
const app = express();

// Connect to MongoDB
async function main(){
    await mongoose.connect('mongodb://localhost:27017/quizApp');
    console.info('db is connected');
}
main();
// Middleware
app.set('view engine', 'ejs');
app.set('views',path.join(__dirname,'/views'));
app.use(express.static(path.join(__dirname,'public')));
app.use(express.urlencoded({extended:true}));
app.use(express.json());

// Routes
const indexRoutes = require('./routes/index');
app.use('/', indexRoutes);

// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.info(`Server is running on port ${PORT}`);
});

маршруты/index.js

const express = require('express');
const router = express.Router();
const Quiz = require('../models/quiz');

router.get('/', async (req, res) => {
    const quizzes = await Quiz.find({});
    res.render('quiz', { quizzes });
});

router.post('/submit', async (req, res) => {
    const answers = req.body;
    console.info(req.body);
    let score = 0;
    const quizzes = await Quiz.find({});
    quizzes.forEach(quiz => {
        if (answers[quiz._id] === quiz.answer) {
            score++;
        }
    });
    res.render('result', { score, total: quizzes.length });
});

module.exports = router;

quiz.ejs

<form id = "quizForm" action = "http://localhost:3000/submit" method = "post">
  <% quizzes.forEach((quiz, index) => { %>
  <div
    class = "question-container"
    id = "question-<%= index %>"
    style = "display: none"
  >
    <p class = "lead"><%= quiz.question %></p>
    <% quiz.options.forEach(option => { %>
    <div class = "custom-control custom-radio">
      <input
        type = "radio"
        id = "<%= 'question' + index + option %>"
        name = "<%= quiz._id %>"
        value = "<%= option %>"
        class = "custom-control-input"
        onclick = "checkAnswer('<%= quiz.answer %>', this)"
      />
      <label
        class = "custom-control-label"
        for = "<%= 'question' + index + option %>"
        ><%= option %></label
      >
    </div>
    <% }) %>
  </div>
  <% }) %>
  <button
    type = "button"
    class = "btn btn-secondary"
    id = "prevBtn"
    onclick = "changeQuestion(-1)"
    disabled
  >
    Previous
  </button>
  <button
    type = "button"
    class = "btn btn-secondary"
    id = "nextBtn"
    onclick = "changeQuestion(1)"
    style = "display: none"
  >
    Next
  </button>
  <button
    type = "submit"
    class = "btn btn-primary"
    id = "submitBtn"
    style = "display: none"
  >
    Submit
  </button>
</form>
<script>
  const questions = document.querySelectorAll(".question-container");
  let currentQuestionIndex = 0;

  function showQuestion(index) {
    questions.forEach((question, i) => {
      question.style.display = i === index ? "block" : "none";
    });
    document.getElementById("questionNumber").textContent =
      `${index + 1}/${questions.length}`;
    document.getElementById("prevBtn").disabled = index === 0;
    document.getElementById("nextBtn").style.display =
      index === questions.length - 1 ? "none" : "inline-block";
    document.getElementById("submitBtn").style.display =
      index === questions.length - 1 ? "inline-block" : "none";
  }

  function changeQuestion(direction) {
    currentQuestionIndex += direction;
    showQuestion(currentQuestionIndex);
  }

  function checkAnswer(correctAnswer, selectedOption) {
    const questionContainer = selectedOption.closest(".question-container");
    const options = questionContainer.querySelectorAll(".custom-control-input");
    options.forEach((option) => {
      const label = questionContainer.querySelector(
        `label[for = "${option.id}"]`,
      );
      if (option.value === correctAnswer) {
        label.style.backgroundColor = "green";
      } else if (option.checked) {
        label.style.backgroundColor = "red";
      }
      option.disabled = true;
    });
    document.getElementById("nextBtn").style.display = "inline-block";
  }

  // Initial display of the first question
  showQuestion(currentQuestionIndex);
</script>

Схема модели викторины

const mongoose = require('mongoose');

const quizSchema = new mongoose.Schema({
    question: String,
    options: [String],
    answer: String
});
module.exports = mongoose.model('Quiz', quizSchema);

Проблема В quiz.ejs, почему форма дает мне пустой объект в консоли, я правильно указываю имя и значение ввода после отправки формы и перехожу к маршрутизатору отправки, который я упоминаю в приведенном выше коде, и я console.info(req.body), он дает мне пустой объект. Я создаю веб-сайт приложения для викторины, и когда я даю все ответы на вопросы и завершаю отправку, он не показывает оценку, и когда я вижу весь свой код, я вижу req, body дает мне пустой объект, почему я также использую промежуточное программное обеспечение чтобы проанализировать сообщение, тогда почему оно дает мне пустой объект

Вы получили это db is connected на консоли? Какую конкретно ошибку вы получаете?

Subha 05.08.2024 14:26

Как выглядит ваша модель викторины?

maximelian1986 05.08.2024 14:30

да, БД подключена, и теперь я упоминаю схему модели теста

Aayush Puri 05.08.2024 16:55

скорее всего, вы меняете значения/форму с помощью функций JavaScript checkAnswer и changeQuestion.. вы можете включить их

traynor 05.08.2024 17:18

Как я могу включить функцию javascript для проверки ответа и изменения вопроса, а затем ты скажешь мне, где я ошибаюсь и как мне это улучшить?

Aayush Puri 06.08.2024 06:26

Откройте панель «Сеть» инструментов разработчика вашего браузера и проверьте запрос POST. Он должен показать вам, как выглядит кузов/полезная нагрузка. Если все выглядит хорошо, значит, проблема на стороне сервера, хотя я не вижу очевидных проблем в предоставленном коде.

Phil 06.08.2024 07:07

Привет! Пожалуйста, проверьте тип контента, который он отправляет на сервер, для этого временно добавьте оператор console.info(Content type: ${req.get('Content-Type')}); в качестве первой строки в обработчике отправки сообщения.

WeDoTheBest4You 07.08.2024 10:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
7
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема связана с функцией JavaScript checkAnswer: она устанавливает для каждого параметра значение disabled, а отключенные параметры не отправляют значения при отправке формы, поэтому вы получаете пустой объект на сервере.

Итак, вам нужно изменить свою логику и предотвратить отключение опции, которая должна отправлять данные.

Например, вы можете отключить неправильные и непроверенные параметры, а к правильному добавить функцию, которая предотвратит его последующий выбор, и тем самым разрешить его отправку вместе с формой, однако он не будет стилизован как disabled, но вы можете оформить его так, чтобы оно выглядело как disabled, например, уменьшить непрозрачность, удалить события указателя или что-то подобное.

Попробуйте этот код:

  if (option.value === correctAnswer) {
    label.style.backgroundColor = "green";
    // leave it enabled, but prevent later selections
    option.onclick = () => false;
    // style it a bit to look like disabled
    option.style.opacity = ".5";
    option.style.pointerEvents = "none";
  } else {
    // disabled wrong and unchecked
    option.disabled = true;
    // style wrong
    if (option.checked) label.style.backgroundColor = "red";
  }

Другие вопросы по теме