CSSファイルの読み込み(02)

今回は、”index.html”ファイルをクライアントに送ります。前回のプログラムで、self.wfile.write(“<h1>Hello HTTP!
</h1>\n”.encode())の部分でデータをクライアントに送っているのですが、この部分を変更します。

hello_02.py

from http.server import HTTPServer, SimpleHTTPRequestHandler

class MyHandler(SimpleHTTPRequestHandler):

    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', "text/html")
        self.end_headers()

        f = open("index.html",'rb')
        self.wfile.write(f.read())
        f.close()

host = ''
port = 8080
httpd = HTTPServer((host, port), MyHandler)
print('serving at port', port)
httpd.serve_forever()

10,12行目に、f = open(“index.html”,’rb’)と f.close()を追加。 11行目のself.wfile.write()の引数をf.read()に変更しました。各関数の詳細は、以下の通りです。

  • open(file_name,mode)
    • file_name: オープンするファイルのパスを伴ったファイル名
    • mode: ファイルのモード
      文字 意味
      r 読み込み用 (デフォルト)
      w 書き込み用。同名のファイルが有る場合上書きされる。
      x 新規ファイルの書き込み用に開くが既に同名のファイルが有る場合、エラーを返す
      a 書き込み用。ファイルが存在する場合は末尾に追記。
      b バイナリモード
      t テキストモード
    • 今回、’rb’モードを指定しているのは、wfile.write()関数がバイナリデータを送信するため。
  • read(): オープンされたファイルからデータを読み出す。
  • close(): ファイルのクローズ。

各ファイルの保存場所と実行

今回はpythonのファイル、”hello_02.py”と”index.html”の2つファイルが有ります。Python HTTP-serverは、pythonスクリプトが実行されているフォルダをルートディレクトリと解釈します。”index.html”を”hello_02.py”と同じフォルダに保存してターミナルから、python3 hello_02.py と実行して下さい。ブラウザに、raspberrypi.local:8080といれれば、前回と同じ画面になります。

これだけではつまらないので

これだけではつまらないので、CSSファイルを読み込んで見ましょう。HPの書式を定義するファイルです。先ずはCSSファイルの作成。ファイルネームを、”http_server_02a.css”とします。

http_server_02a.css

@charset "UTF-8";

.t_font {
        font-size: 64px;
        font-weight:bold;
        font-style: italic;
        color: #ff0000;
}

.b_frame {
        width: 600px;
        background: #363636;
        padding: 15px;
        border-radius: 10px;
        margin-top: -30px;
        margin-right: 10px;
}

次にindexファイル。新しいindexファイルを、”index_02a.html”とします。

index_02a.html

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="stylesheet" type="text/css" href="./http_server_02a.css" >
        <title>http-server 1.0</title>
    </head>
    <body>
        <center>
            <div class="b_frame">
   	            <div class="t_font">HTTP-Server 1.0</div>
            </div>
        </center>
    </body>
</html>
  • 6行目でCSSファイルを定義
  • 10行目で全体を中心に配置
  • 11行目で表示枠を定義。ここで、CSSのb_frameを使用
  • 12行目で文字を表示。ここで、CSSのt_fontを使用。

最後にPythonファイル。ファイル名は、”hello_02a.py”とします。

hello_02a.py

from http.server import HTTPServer, SimpleHTTPRequestHandler

class MyHandler(SimpleHTTPRequestHandler):

    def do_GET(self):

        if self.path == "/":
            self.path = "index_02a.html"
            dataType = "text/html"
        if self.path.endswith(".css"):
            self.path = "." + self.path
            dataType = "text/css"

        f = open(self.path,'rb')
        self.send_response(200)
        self.send_header('Content-type', dataType)
        self.end_headers()
        self.wfile.write(f.read())
        f.close()

host = ''
port = 8080
httpd = HTTPServer((host, port), MyHandler)
print('serving at port', port)
httpd.serve_forever()
  • 7行目 ”index_02a.html”の判別
  • 10行目 ”http_server_02a.css”の判別
  • 14から19行 データの送信

です。これらのファイルをRaspberry Piの同じフォルダーに保存して、

ターミナルで保存されているフォルダーで、$ python3 hello_02a.py と実行して下さい。Webブラウザで、”raspberrypi.local:8080″にアクセスすればこんな画面が出ます。

流れを説明すると

  • ブラウザのURL欄に”raspberrypi.local:8080”と入力してリクエストを行うと、”GETリクエスト”となりクエリとして、”/”がサーバに送られます。
  • サーバはGETリクエストが来たので下記の def do_GET(self): を実行します。
  • 引数 self がクエリのポインター(?)となっていてこれを用いてクエリの値を参照出来ます。
  • self.pathでパスを参照出来るのですが今回は、”/” のなので、7行目のif で判断されます。
  • 8,9行で、”index_02a.html”とパラメータをセットして14行以下でデータを送信します。

CSSファイルの読まれるタイミングはHTMLファイル、”<meta name=”viewport” content=”width=device-width,initial-scale=1″> 箇所です。この時点でクライアントからGETリクエストが要求されクエリは、”/http_server_02a.css”となります。

  • if self.path.endswith(“.css”): はself.pathの下から4文字が”.css”だったら真となります。ここで拡張子の判定を行っています。
  • iself.path = “.” + self.path: この時点でself.pathは、”/http_server_02a.css”。 トップに、”.”を追加してファイルのパスを作っています。
  • それ以降は、”index_02a.html”と同じ。

こんな感じです。次回はこのブラウザにボタンを追加してみたいと思います。