Когда я вызываю 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 не работает в вашем маршруте app.post("/publish-score"), скорее всего, связана с асинхронным характером функции readFileSync.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Используйте 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)
}
});
Пробовал и то, и другое, не получилось.
Оказывается, причина была в том, что я использовал fetch для отправки POST-запроса. fetch не выполняет автоматическое перенаправление — поэтому клиент получал HTML-файл (виден на вкладке «Сеть»), но не перенаправлялся на эту страницу. Кажется, что можно перенаправить с помощью fetch, но я решил вместо этого использовать фиктивный элемент формы и отправить его с помощью JS.
Как сейчас написано, ваш ответ неясен. Пожалуйста, отредактируйте , чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Более подробную информацию о том, как писать хорошие ответы, вы можете найти в справочном центре.
Вероятно, вы спрашиваете о
res.sendFile(__dirname + "/public/dup_name.html"). Вы уверены, что ваш код соответствует этомуifусловию? Видите лог изconsole.info("Name used already!")? К вашему сведению, вы не отправляете ответ, если имя не найдено.