CSS样式未应用于节点服务器提供的HTML页面(无express)

e5nszbig  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(130)

我发送这个HTML文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <p>Home</p>
</body>

引用这个简单的CSS文件:

p {
    color: blue
}

使用这段简单的NodeJS代码:

require("http").createServer((request, response) => {
    response.setHeader("Content-type", "text/html")
    response.setHeader("Access-Control-Allow-Origin", "*")
    response.statusCode = 200
    response.end(require("fs").readFilSync("index.html", "utf8"))
}).listen(port)

它工作得很好,只是样式没有应用到Chrome中的页面(文本不是蓝色的)。
为什么呢?我必须也发送css文件吗?或者我必须编辑HTML文件的内容并在发送之前在<style>标签中添加样式吗?
我没有使用express,因为我正在练习原始Web开发。(除了Node)

qrjkbowd

qrjkbowd1#

发生这个问题是因为你的服务器只为每个请求提供HTML文件,所以当浏览器向你的服务器请求CSS文件时,它没有得到响应。
作为一种解决方案,您应该修改服务器,使其在接收到以.css结尾的HTTP请求(请求CSS文件)时提供CSS文件。

const fs = require("fs");
const path = require("path");

port = 3000;
require("http")
  .createServer((request, response) => {
    if (request.url === "/") {
      response.setHeader("Content-type", "text/html");
      response.setHeader("Access-Control-Allow-Origin", "*");
      response.statusCode = 200;
      response.end(require("fs").readFileSync("index.html", "utf8"));
    }
    else if (request.url.match(".css$")) {
      const cssPath = path.join(__dirname, request.url);
      const fileStream = fs.createReadStream(cssPath, "UTF-8");
      response.writeHead(200, { "Content-Type": "text/css" });
      fileStream.pipe(response);
    }
  })
  .listen(port);
xcitsw88

xcitsw882#

我并不是CORS里的好人,
如果您没有为这个操作处理一个特殊的请求处理程序,那么任何浏览器或客户端都不会从正在运行的服务器接收任何文件或数据。
这意味着,您必须为style.css文件设置一个特殊请求,以便当浏览器尝试通过新请求获取该文件时,它可以获取该文件。
你可能会想,如果我有很多很多样式,脚本,媒体,字体文件,我用我的html连接它们,我需要为他们所有,在这里你可以把他们放在一个目录,然后设置一个特定的处理程序,获得第一部分,然后将其与您的公共文件的文件夹匹配,然后使用您的请求url的末尾的路径找到这个公共文件夹内的文件,因此您可以轻松获取该文件夹中任何文件。
我知道你可能会说你正在使用response.setHeader("Access-Control-Allow-Origin", "*"),从我对CORS的了解来看,这是用来让其他服务器请求你自己的文件的,如果你不处理对这些文件的一些请求,这将不会完成。
多说!
开始干活吧
只需将css文件和其他静态文件(如styles | scripts | media | fonts)放在一个文件夹中,我们称之为public
现在您需要处理对任何静态文件的特定请求,并从该文件夹中获取它,因此,您的项目结构将如下所示:

  • 根目录/:
  • index.js
  • index.html
  • 公共/
  • style.css

现在你的html和css文件是一样的,唯一的变化是style.css文件的路径,它移动到public/目录。
但是您的index.js(服务器文件)将如下所示:

let http = require("http")
let fs = require("fs")

let server = http.createServer((req, res) => {
    let url = req.url    // get the url of the request
    if( url.split("/")[1] === "public" ) {
        handlePublic(url, req, res)    // run seperated code if the request contanis public/ in the first of it
    }
    else {
        // here the normal code for all other non public requests
        let html = fs.readFileSync("./index.html")
        res.setHeader("Content-type", "text/html")
        res.statusCode = 200
        res.end(html)
    }
})

function handlePublic(url, req, res) {
    let file = fs.readFileSync("./" + url)  // which will send any file from public/
    res.end( file )
}

server.listen( 3000 )

现在,任何你放在public文件夹中的文件,以及试图通过一个http请求来访问的文件(url以public/开头),都将被正确地发送到客户端,但是public目录之外的所有其他文件都将从你还没有处理的请求中保存。
希望我能帮上忙。

相关问题