0

我最近开始通过创建一个简单的待办事项列表来学习 Express.js 和 mongoose,现在我被一个基本的东西困住了。

当我尝试根据 URL 参数在动态路由中呈现 EJS 文件时,我无法应用stylesheet.css存储在publicEJS 文件夹中的文件,并且浏览器控制台中显示了以下错误消息。错误信息:

Refused to apply style from 'http://localhost:3000/mylist/css/styles.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

当然,URL 请求是http://localhost:3000/mylist/css/styles.css.

另一方面,在主路由中渲染的同一个 EJS 文件能够访问stylesheet.css. 请求 URL 是http://localhost:3000/css/styles.css.

所以我想无论我尝试呈现什么,请求 URL 都必须http://localhost:3000/css/styles.css在我的文件结构中。但是,当我在基于 URL 参数的动态路由中呈现为 EJS 时,我不知道如何摆脱mylistfrom 。http://localhost:3000/mylist/css/styles.css

我的代码有什么问题?你如何解决它?

文件结构:

在此处输入图像描述

应用程序.js

const express = require("express");
const mongoose = require("mongoose");
const app = express();

app.set('view engine', 'ejs');
app.use(express.static("/public"));

mongoose.connect("mongodb://localhost:27017/todolistDB", {useNewUrlParser: true, useUnifiedTopology: true});

const itemsSchema = mongoose.Schema({ name: String });
const customListsSchema = mongoose.Schema({ name: String, items: [itemsSchema] });

const Item = mongoose.model("Item", itemsSchema);
const CustomList = mongoose.model("CustomList", customListsSchema);

app.get("/", (req, res) =>  {
  Item.find((err, foundItems) => {
    if (!err) {
      res.render("list", { listTitle: "Today", newListItems: foundItems });
    }
  });
});

app.get("/mylist/:customListName", (req, res) => {
  const customListName = req.params.customListName;
  CustomList.findOne({ name: customListName }, (err, foundCustomList) => {
    if (!err) {
      if (foundCustomList) {
        res.render("list", {
          listTitle: foundCustomList.name,
          newListItems: foundCustomList.items
        });
      } else {
        const customList = new CustomList({ name: customListNamem });
        customList.save((err) => {
          if (!err) {
            res.redirect("/mylist/" + customListName);
          }
        });
      }
    }
  });
});

列表.ejs:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>To-Do List</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>
  <div class="box" id="heading">
    <h1> <%= listTitle %> </h1>
  </div>
  <div class="box">

    <form action="/delete" method="post">
      <% newListItems.forEach((newListItem) => { %>
        <div class="item">
          <input type="checkbox" name="checkbox" value="<%= newListItem._id %>" onchange="this.form.submit()">
          <p><%= newListItem.name %></p>
        </div>
      <% }); %>
    </form>

    <form class="item" action="/" method="post">
      <input type="text" name="newItem" placeholder="New Item" autocomplete="off">
      <button type="submit" name="listName" value="<%= listTitle %>">+</button>
    </form>

  </div>
</body>
</html>

我也尝试并替换app.use(express.static("/public"));app.use(express.static(__dirname + "/public"));,但它也不起作用。

4

2 回答 2

1

我想出了如何自己修复错误。

这是因为 EJS 中样式表的路径是相对路径。看来它必须是一条绝对路径。

所以我只是添加了一个正斜杠/<link rel="stylesheet" href="css/styles.css"><link rel="stylesheet" href="/css/styles.css">.list.ejs

现在它适用于app.use(express.static(__dirname + "/public"));in app.js,但它仍然不适用于app.use(express.static("/public"));.

他们之间有什么区别?

于 2021-01-21T04:33:54.657 回答
0

__dirname加上path.join()创建目录的绝对路径,它将在运行它的机器上工作。

您正在做什么: app.use(express.static(path.join(__dirname, 'public')));将静态文件夹设置/Absolute/Path/To/Repo/public/__dirname“/Absolute/Path/To/Repo/”部分的位置。

所以在我的电脑上运行它会返回: /home/proto/UWebDev/Playground/myapp/public 在你的电脑上它会是那个特定public目录的路径。

相反,在您的初始代码中,您只需使用:

app.use(express.static("/public"); 如果控制台记录在任何地方将返回/public。这是我假设不在您的仓库中的绝对路径,因为,我还没有听说有人从机器的根目录中创建仓库。

对于它的价值,你所做的一切app.js 使它在前端开始的任何东西/实际上都是引用/ABS/PATH/TO/REPO/public/; 在这个特定的场景中,我相信简单地替换你的原始"/public"文件"./public"也会起作用(除了/像你所做的那样添加到 css 的路径中。

旁注:path.join(__dirname,'public)===path.join(__dirname,'/public')它的价值。

我对开发还很陌生,所以如果有人看到我犯了错误或过于简单化的问题,请指出,但希望这有助于访问此页面寻找答案的人。

于 2021-08-13T17:06:59.570 回答