23
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node.jsでhttpサーバを立てた際にCSSが読み取れない場合の対処法について

Posted at

目的

同じ問題に遭遇した方への情報共有および、自分の備忘録として作成します。

概要

Node.jsで、以下の方法(httpモジュール)でhttpサーバを立てて、そのサーバにアクセスした際に、CSSが読み取れない場合の対処法を述べます。

server.js
var http = require('http');
var fs   = require('fs');

var http_server = new http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end(fs.readFileSync('./index.html', 'utf-8'));
}).listen(3000);
console.log('Server running at http://localhost:3000/');

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>test</title>
    <link rel="stylesheet" href="css/style.css" type="text/css">
  </head>
  <body>
    <!-- 本文 -->
  </body>
</html>

結論

サーバが、CSSのMIMEタイプ("text/css")を読み取れるようになっていないことが原因でした。

問題の対処法

以下の通り server2.js に修正することで、ちゃんとCSSのMIMEタイプを読み取って、クライアントに転送することができます。
コードについて、以下3点をコンセプトとして設計しました。

  1. CSSを読み取り可能にする。
  2. "index.html"以外も応答可能にする。
  3. CSS以外のMIMEタイプも、追記可能なコードにする。(せっかくだから)
server2.js
var http = require('http');
var fs   = require('fs');
var path = require('path');
var mime = {
  ".html": "text/html",
  ".css":  "text/css"
  // 読み取りたいMIMEタイプはここに追記
};

var http_server = new http.createServer(function(req, res) {
  
  if (req.url == '/') {
    filePath = '/index.html';
  } else {
    filePath = req.url;
  }
  var fullPath = __dirname + filePath;
  
  res.writeHead(200, {"Content-Type": mime[path.extname(fullPath)] || "text/plain"});
  fs.readFile(fullPath, function(err, data) {
    if (err) {
      // エラー時の応答
    } else {
      res.end(data, 'UTF-8');
    }
  });
}).listen(3000);
console.log('Server running at http://localhost:3000/');

所見

  • MIMEタイプについて(というよりサーバの挙動について)理解していなかったため、ブラウザのコンソールでのエラーの意味が分かりませんでした。このため、問題の原因の切り分けができず、ググっては大量の情報に右往左往してしまいました。
  • サーバの動作についての知識が不足していましたが、今回応答処理をコーディングしたことで(ちょっとは)理解が深まったと感じます。継続して習得を目指します。

参考文献

まず @tatesuke 氏から、以下の記事を紹介して貰い、原因に気づけました。
サーバには"MIMEタイプ"設定があり、サーバが所望のファイルを読み取り可能なように設計していないと、クライアント側にファイルを伝送できないことを知りました。

stackoverflow: "Using node.js to serve up basic web page with CSS and JS includes"
" Simple: you're setting the Content-Type header to text/html, always. Also, it will always serve your index.html file. "(抜粋)

以下のページがMIMEタイプの理解の助けになりました。

とほほのWWW入門: 拡張子とMIMEタイプ
" ブラウザが xx.gif というファイルをWEBサーバーに要求する際、WEBサーバーはxx.gifの内容(データ)を「これは image/gif タイプのデータです」と言いながら返却してくれます。これにより、ブラウザは受け取ったデータを正常に処理することができるのです。 "(抜粋)

コードの内容に関しては、以下Qiita記事(@morou氏)が参考になりました。

Qiita: node.jsで動作するシンプルなWebサーバ

Node.jsマニュアル・ドキュメンテーション

23
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?