对不起,如果我分享太多(或太少!)当代码包含在这样的多个文件中时,我不知道如何提供代码。
在这个小项目中,我的app.js服务器使用了express和ejs。我有一个"/compose“的路线,它创建一个博客文章的”标题“和”内容“。然后将其推入一个名为“post”的全局数组中。
在"/posts“路由中,我的意图是服务器在包含post的”post“数组上循环,并将正确的post标题与URL中给定的"postName”参数匹配。(我试图用字符串上的.toLowerCase()方法使标题不区分大小写。)
但是,当我这样做的时候,页面就会停止,而不会实际加载。但是,一个奇怪的错误是,如果我“重新加载”服务器(我正在运行nodemon),甚至对app.js代码进行小的更改,例如更改逗号或注释一行,比如nodemon重新加载,页面将显示所请求的信息。
// This is my app.js code
const express = require("express");
const ejs = require("ejs");
const app = express();
app.set('view engine', 'ejs');
app.use(express.urlencoded({
extended: true
}));
app.use(express.static(__dirname + "/public"));
const posts = [];
app.get("/posts/:postName", (req, res) => {
const requestedTitle = req.params.postName.toLowerCase();
posts.forEach(post => {
const storedTitle = post.title.toLowerCase();
if (requestedTitle === storedTitle) {
res.render("post", {
post: post
});
}
});
});
app.post("/compose", (req, res) => {
const post = {
title: req.body.postTitle,
content: req.body.postBody
};
posts.push(post);
res.redirect("/")
})<!-- This is my "Post" route HTML code (a partial called post.ejs) -->
<h1>This is
<%= post.title%>
</h1>
<!-- This is my "Compose" route HTML Code (a partial called compose.ejs) -->
<h1>Compose</h1>
<form action="/compose" method="POST">
<div class="form-group">
<label for="postTitle">Title</label>
<input class="form-control" type="text" name="postTitle" autofocus>
<label for="postBody">Post</label>
<textarea class="form-control" name="postBody" id="" cols="30" rows="5"></textarea>
</div>
<button class="btn btn-primary" type="submit" name="button">Publish</button>
</form>
发布于 2022-03-23 14:55:37
我看到的主要问题是,您的app.get("/posts/:postName", ...)路由需要始终发送一个并且只有一个http响应。按照现在的编码方式,如果找不到匹配的帖子,它将不会发送响应,如果找到多个响应,它将尝试发送多个响应。这两种情况都是个问题。
有一种方法可以解决这个问题:
app.get("/posts/:postName", (req, res) => {
const requestedTitle = req.params.postName.toLowerCase();
for (let post of posts) {
const storedTitle = post.title.toLowerCase();
if (requestedTitle === storedTitle) {
res.render("post", {
post: post
});
return;
}
}
// send some sort of response here with a 404 status
res.sendStatus(404);
});作为对您看到的服务器行为的一个可能的解释,浏览器将只在同一时间向同一主机发送那么多在运行中的请求。因此,如果使用原始代码,您正在处理的URL没有匹配的帖子,这些URL将不会从服务器获得发送回浏览器的响应,而这些请求仍将等待响应。最终,浏览器将到达它将发送到主机的最大请求,直到其中一些请求完成为止。因此,您的服务器似乎对新请求没有响应,而实际上它只是在等待先前的请求完成。您必须始终从您的服务器向每个传入的http请求发送一个和唯一一个响应。
我假设这个posts数组可能只是一个临时的存储机制,但是如果您用一个Map对象替换这个数组,并以小写标题作为键的话,效率会更高。然后,您可以使用一个map.get()操作直接在Map对象上查找匹配的标题,而不是遍历整个数组。
https://stackoverflow.com/questions/71589167
复制相似问题