Javascript/Node.js 服务器 - 查询 JSON 文件中的数据集以创建 URL

Javascript/Node.js server - querying dataset in JSON file to create URLs

应用描述:

我正在尝试创建一个 HTML 模板,该模板接收卡片对象数组并使用其中包含的数据生成页面以显示卡片列表。对于此列表中的每张卡片,我应该有一个指向该特定卡片的 URL 的 link(例如,http://localhost:3000/cards/that_card 's_id) 和 link 文本应指示卡的名称和唯一 ID。

基本上,我会在我的命令栏中输入节点 server.js,然后打开 google chrome 并在我的地址栏中输入 localhost:3000,它会带我到显示所有 link 的卡片 html 页面。当我点击一张特定的卡片时,它应该将我带到另一个 html 页面,该页面只显示显示卡片名称和卡片费用的文本。

问题:

我创建了一个服务器。问题是,当我在地址栏中输入 localhost:3000 时,页面似乎没有加载。 我什至无法测试我的代码是否正常工作该页面根本不加载。该页面仅显示“此页面无效”和“本地主机未发送任何数据”。有人告诉我这是因为在我的服务器代码中,我正在监听请求 urls /cards/cards//cards? 。当我尝试访问 localhost:3000 时,请求 url 是 / ,因此我正在尝试访问我未处理的 url。

server.js:

const pug = require("pug");
const fs = require("fs");
const http = require("http");
const url = require('url')

let cardData = require("./cards.json");
let cards = {}; 
cardData.forEach(card => {
    cards[card.id] = card;
});

//Initialize server
const server = http.createServer(function(request, response) {
    if (request.method === "GET") {
        if (request.url === "/cards") {     
              response.statusCode = 200;
              response.write(pug.renderFile("./views/cards.pug", { cards: cards }));
              response.end();
        }else if (request.url.startsWith("/cards/")) {
            const paths = request.url.split("/");
            const cardId = paths[2];
            if (cards.hasOwnProperty(cardId)) {
                const targetCard = cards[cardId];
                response.statusCode = 200;
                response.write(
                    pug.renderFile("./views/card.pug", { card: targetCard })
                );
                response.end();
                return;
            } else {
                response.statusCode = 404;
                response.end();
                return;
            }
        } else if (request.url.startsWith("/cards?")) {
            const params = request.url.split("?");
            const [_, value] = params[1].split("=");
            const limit = parseInt(value);
            if (limit < 1) {
                response.statusCode = 400;
                response.write("Invalid query");
                response.end();
                return;
            }
            const responseCards = Object.values(cards).slice(0, limit);
            response.statusCode = 200;
            response.write(
                pug.renderFile("./views/cards.pug", { cards: responseCards })
            );
            response.end();
            return;
        }
    } else {
        response.statusCode = 404;
        response.write("Unknown resource.");
        response.end();
    }
});

//Start server
server.listen(3000);
console.log("Server listening at http://localhost:3000");

cards.json:

[
    {
    "artist":"Arthur Bozonnet",
    "attack":3,
    "collectible":true,
    "cost":2,
    "flavor":"And he can't get up.",
    "health":2,
    "id":"AT_003",
    "mechanics":["HEROPOWER_DAMAGE"],
    "name":"Fallen Hero",
    "rarity":"RARE"
    },

    {
    "artist":"Dan Scott",
    "attack":3,
    "collectible":true,
    "cost":4,
    "flavor":"Is he aspiring or inspiring? Make up your mind!",
    "health":5,
    "id":"AT_006",
    "mechanics":["INSPIRE"],
    "name":"Dalaran Aspirant",
    "rarity":"COMMON"
    }
]

cards.pug:

html
    head
        title Cards
body

    div#main
        h1 List of Cards:
        each card in cards
            a(href="/cards/" + card.name) #{card.id}
            br

card.pug:

html
    head
        title #{card.name}
body

    div#main
        h1 Name: #{card.name}, Cost: $#(card.cost)

我假设您有充分的理由不使用 express 或等效的网络服务器框架,尽管我强烈建议您对除最小用例以外的所有用例都使用此类工具,但我'根据您当前的设置,我仍然会尝试为您指明正确的方向。

您没有“/”的路由处理程序: 当您转到 localhost:3000 时服务器挂起的原因是请求处理函数对“GET /”没有任何行为。 如果您改为访问 localhost:3000/cards

,您应该会看到您的回复

通过 id 提供卡片: 通过 id 提供卡片的最佳方法(考虑到技术限制)是这样的(为简洁起见省略了其余代码):

} else if (request.url.startsWith("/cards/")) {
      const paths = request.url.split("/");
      const cardId = paths[2];
      const card = cards.find((card) => card.id === cardId);

      if (!card) {
        response.statusCode = 404;
        response.end();
        return;
      }

      response.statusCode = 200;
      response.write(pug.renderFile("./views/card.pug", { card: card }));
      response.end();
      return;
    } 

一般方法 同样,我会认真考虑使用 express,如果您的项目继续增长,它会迫使您将代码分成更易读的片段,并使您的生活 更轻松。举例来说,这是你的一些代码在 express 中的样子:

const app = require("express")()

app.get("/", (req, res) => {
  return res.sendFile("./views/home.pug")
})

app.get("/cards", (req, res) => {
  return res.sendFile("./views/cards.pug")
});

app.get("/cards/:id", (req, res) => {
  const card = getCard(req.params.id);

  if (!card) {
    return res.sendStatus(404)
  }

  return res.sendFile("./views/cards.pug", {card })
});

这段代码并不完整 - 但我希望它能向您展示您的服务器可以看起来多么干净!我确实希望它能有所帮助 - 祝您编写应用程序好运