Node.js Express res.sendFile ничего не делает при вызове в app.post

Когда я вызываю res.sendFile внутри app.post("/publish-score"...), ничего не происходит. Код состояния запроса — 200. Есть идеи?

Вот код моего приложения.

import express from "express";
import Boggle from "solve-boggle";
import { rateLimit } from "express-rate-limit";
import { dirname } from "path";
import { fileURLToPath } from "url";
import { readFileSync, writeFile } from "fs";
const __dirname = dirname(fileURLToPath(import.meta.url));

const app = express();
const PORT = process.env.PORT || 5001;

let user_name;
let board;

app.use(express.urlencoded({extended:true}));
app.use(express.static(__dirname));
app.use(express.json());

app.get("/", (req, res) => {
    res.sendFile(__dirname + "/public/index.html");
});

app.get("/new-board", (req, res) => {
    console.info("new board req: ", req.body);
    board = new Boggle(5);
    res.send(board);
});

app.get("/solution", (req, res) => {
    board.solve(words => {
        res.send(words);
    });
});

app.get("/name", (req, res) => {
    res.sendFile(__dirname + "/public/play.html");
})

// using get instead of post to prevent form resubmission
app.post("/name", (req, res) => {
    user_name = req.body.name;
    console.info("body: ", req.body);
    console.info("name: ", req.body.name);
    res.sendFile(__dirname + "/public/play.html");
});

// publish score
app.post("/publish-score", (req, res) => {
    console.info("request name: ", user_name);
    console.info("request score: ", req.body.score);

    let user_score = req.body.score;

    // read scores file
    let data = readFileSync("./data/scores.json", (error, data) => {
        if (error){
            console.info(error);
            return;
        };
    });
        
    // check if name already in score list
    let names = [];
    let scores_data = JSON.parse(data);
    scores_data.daily_puzzle.scores.map((entry) => names.push(entry.name));
    console.info("names: ", names);
    if (names.includes(user_name)) {
        console.info("Name used already!");
        res.sendFile(__dirname + "/public/dup_name.html");
        return;
    };

    // add name and score to list
    let push_name = user_name;
    let push_score = user_score;
    if (user_name == undefined){push_name = "NoName"}; 
    if (user_score == undefined){push_score = "NoScore"}; 
    scores_data.daily_puzzle.scores.push({
        "name": push_name,
        "score": push_score
    });

    // console.info(scores_data.daily_puzzle.scores);        

    writeFile("./data/scores.json", JSON.stringify(scores_data), (error) => {
        if (error) {
            console.info("An error has occurred ", error);
            return;
        }
        console.info("Data written successfully to the file");
    });  
    // }); 
});

app.listen(PORT, () => {console.info(`Listening on port ${PORT}`)});

Я бы хотел, чтобы сервер отправлял dup_name.html, когда пользователь пытается опубликовать партитуру с именем, которое уже есть в scores.json. Я пробовал переместить его в другое место в a[[.pot, но безуспешно.

Вероятно, вы спрашиваете о res.sendFile(__dirname + "/public/dup_name.html"). Вы уверены, что ваш код соответствует этому if условию? Видите лог из console.info("Name used already!")? К вашему сведению, вы не отправляете ответ, если имя не найдено.

Phil 07.05.2024 04:28

Да, я вижу сообщение «Имя уже использовано!» в консоли. Спасибо за информацию - это предполагаемое поведение (на данный момент).

Seth Strumwasser 07.05.2024 10:03

Проблема с тем, что res.sendFile не работает в вашем маршруте app.post("/publish-score"), скорее всего, связана с асинхронным характером функции readFileSync.

Ravi Chauhan 07.05.2024 10:08
Поведение ключевого слова "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) для оценки ваших знаний,...
0
3
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Используйте fs.readFile (неблокирующую версию) и обрабатывайте результат асинхронно.

app.post("/publish-score", (req, res) => {
  console.info("request name: ", user_name);
  console.info("request score: ", req.body.score);

  let user_score = req.body.score;

  // Read scores file asynchronously
  fs.readFile("./data/scores.json", (error, data) => {
    if (error) {
      console.info(error);
      return res.sendStatus(500); // Handle error
    }

    const scores_data = JSON.parse(data);

    // Check for duplicate name
    const names = scores_data.daily_puzzle.scores.map((entry) => entry.name);
    if (names.includes(user_name)) {
      console.info("Name used already!");
      return res.sendFile(__dirname + "/public/dup_name.html");
    }

    // Add name and score to list (rest of the logic remains the same)
    // ...
  });
});

ИЛИ

app.post("/publish-score", async (req, res) => {
    console.info("request name: ", user_name);
    console.info("request score: ", req.body.score);

    let user_score = req.body.score;

    try {
        // Read scores file asynchronously
        const data = await fs.promises.readFile("./data/scores.json");
        const scores_data = JSON.parse(data);

        // Check if name already in score list
        const names = scores_data.daily_puzzle.scores.map((entry) => entry.name);
        console.info("names: ", names);
        if (names.includes(user_name)) {
            console.info("Name used already!");
            return res.sendFile(__dirname + "/public/dup_name.html");
        }

        // Add name and score to list
        let push_name = user_name || "NoName";
        let push_score = user_score || "NoScore";
        scores_data.daily_puzzle.scores.push({ name: push_name, score: push_score });

        // Write data to scores.json asynchronously
        await fs.promises.writeFile("./data/scores.json", JSON.stringify(scores_data));
        console.info("Data written successfully to the file");
        
        // Success message or redirect (optional)
        // res.send("Score published successfully!");
        
    } catch (error) {
        console.error("Error processing score:", error);
        // Handle errors appropriately (e.g., send error response)
    }
});

Пробовал и то, и другое, не получилось.

Seth Strumwasser 07.05.2024 10:39
Ответ принят как подходящий

Оказывается, причина была в том, что я использовал fetch для отправки POST-запроса. fetch не выполняет автоматическое перенаправление — поэтому клиент получал HTML-файл (виден на вкладке «Сеть»), но не перенаправлялся на эту страницу. Кажется, что можно перенаправить с помощью fetch, но я решил вместо этого использовать фиктивный элемент формы и отправить его с помощью JS.

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