4. HTTPサーバを使う

更新日: 2026.02.25

実用例

今回は実際にサーバのHPをコントロール画面として利用する為の基本的な説明です。 index.html、 http_server.js、 http_server.css、 http_server.pyの4つの ファイルを用意しそれぞれについて説明していきます。

index.html

index.html 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.css" > <title>http-server 1.0</title> </head> <body> <center> <div class="b_frame"> <div class="t_font"><u>HTTP-Server 1.0</u></div><br> <form method='get'> <button type='submit' name='btn0' value='a' id="led">OFF</button> <button type='submit' name='btn1' value='b' >時間</button> </form> <a href="./time.txt" download="time.txt" style="font-size: 28px; color:white">時間ファイル</a> <br> <a href="./test.png" download="test.png" style="font-size: 28px; color:white">画像ファイル</a> <form method='get'> <button type='submit' name='m_dir' value='c' >ファイルリスト</button> </form> <a href="./file_list.txt" download="file_list.txt" style="font-size: 28px; color:white">ファイルリスト</a> </div> </center> <script src="./http_server.js"></script> </body> </html>

http_server.css、http_server.js と合わせて下記の様に表示されます。 コントロール画面でよく使う機能を含めています。

Control Panel
  • リンクファイルの読み込み
    • 6行:<link rel="stylesheet" type="text/css" href="./http_server.css" >
    • 26行:<script src="./http_server.js"></script>
  • 14行:<button type='submit' name='btn0' value='a' id="led">OFF</button>
    • このボタンでGPIOにつながれたLEDをオンオフします
  • 15行:<button type='submit' name='btn1' value='b' >時間</button>
    • このボタンでPythonの関数を使って現在の時間を"time.txt"というファイルに書き込みます。
  • 17行:"time.txt"をダウンロード
    • これはサーバが作製したファイル。
  • 19行:"test.png"をダウンロード
    • これはサーバに元々有ったファイル。
  • 21行:<button type='submit' name='m_dir' value='c' >ファイルリスト</button>
    • ホームディレクトリをLinuxのコマンドを使って”file.txt"に保存
  • 23行:<a href="./file_list.txt" dwnload="......color:white">ファイルリスト</a>
    • "file_list.txt"のダウンロード

http_server.css, http_server.js

http_server.jsは最後にLEDの状態をサーバから受け取っています

http_server.css css
@charset "UTF-8"; .t_font { font-size: 32px; font-weight: bold; font-style: italic; color: #ff0000; } .b_frame { width: 400px; background: #363636; padding: 15px; border-radius: 10px; margin: 0 auto; margin-top: 10px; } button { display: block; margin: 10px; line-height: 30px; cursor: pointer; color: #fff; background: #228b22; border-radius: 10px; font-size: 18px; width: 120px; }
http_server.js javascript
document.addEventListener('DOMContentLoaded', function (event) { let xhr = new XMLHttpRequest(); xhr.open('GET', "http://raspberrypi.local:8080/?80=1"); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState === 4 && xhr.status === 200) { console.log( xhr.responseText ); if(xhr.responseText[0] == "1"){ document.getElementById("led").style.backgroundColor = "red"; document.getElementById("led").innerHTML = "ON"; } } } });

http_server.py

http_server.py python
from http.server import HTTPServer, SimpleHTTPRequestHandler from urllib.parse import urlparse,parse_qs import os from gpiozero import LED import datetime import subprocess def file_list(): subprocess.run('date +"%Y/%m/%d %H:%M:%S" > file_list.txt', shell=True) subprocess.run("ls >> file_list.txt", shell=True) def get_time(): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d %H:%M:%S') fp = open("time.txt",'w') fp.write(time_str) fp.close() class MyHandler(SimpleHTTPRequestHandler): def do_GET(self): global btn_0 allowed_extensions = {'.html', '.css', '.js', '.ico', '.png', '.txt'} _, ext = os.path.splitext(self.path) if self.path == "/" or ext.lower() in allowed_extensions: return super().do_GET() else : self.send_response(200) self.send_header('Content-type', "text/html") self.end_headers() parsed = urlparse(self.path) params = parse_qs(parsed.query) a = next(iter(params)) flg = 1 #----- LED ON/OFF -------------- if a == "btn0": btn_0 ^= 1 if btn_0 == 1 : led.on() else : led.off() print("ボタン0が押されました") #----- 時間の取得 ----------------- elif a == "btn1": get_time() print("ボタン1が押されました") #----- ファイルリストの作製 ------- elif a == "m_dir": file_list() #----- 状態を送る ----------------- elif a == "80": self.wfile.write(str(btn_0).encode("utf-8")) flg = 0 if flg == 1: fp = open("index.html",'rb') self.wfile.write(fp.read()) fp.close() #--------------------------------------------------------- btn_0 = 0 led = LED(17) led.off() get_time() file_list() host = '' port = 8080 httpd = HTTPServer((host, port), MyHandler) print('serving at port', port) httpd.serve_forever()
  • 24から28行:リクエストの仕分け
    • 24行:予めコード内で使う拡張子を配列に定義
    • 25行:self.pathをファイルネームと拡張子に分解
    • 26行:self.pathが"/" か拡張子が登録した中に有るかチェック
    • 27行:Trueなら、super().do_GET()を実行
      • super().do_GET()は以下のファイルを処理
        • index.html
        • http_server.css
        • http_server.py
        • time.txt
        • test.png
        • file_list.txt
  • 29行以下はデータの解読とその処理です。
  • 29から31行:クライアントにリクエストを受けた事を送信
  • 33から35行:データの取り出し
    • 34行:params = parse_qs(parsed.query)
      • parse_qs(parsed.query)はクエリを辞書型に変換する関数です。
      • HTMLの”name”がキーに”value”が要素になります。
      • HTMLで”name”と”value”をセットしないとこの関数は動作しません。
  • 38から45行:LEDボタンの処理
    • HTMLのname='btn0'が押されるとここが実行されます。
    • 操作の内容はGPIOの管理です。
  • 47から50行:現在P時間の保存(Pthonの関数を使用)
    • HTMLのname='btn1'が押されるとここが実行されます。
    • ユーザが宣言した関数get_time()が実行されます
    • 現在の時間を取得し"time.txt"に保存します。
  • 52から55行:ファイルリストの作製(Linuxのコマンドを使用)
    • HTMLのname='m_dir'がクリックされるとここが実行します。
    • Linuxのコマンドを使用して現在の時間とホームディレクトリの内容を"file_list.txt"に保存

まとめ

Python Http-Serverの利点は以下の通り。

  • GPIOの制御が簡単に出来る
  • Pythonの関数またはユーザが定義した関数が使える
  • Linuxのコマンドも使用出来る。

次回は

開発途中でHTTPではなくHTTPSのサーバの使用を求められる事が有ります。 次回はHTTPS(SSL)サーバについて説明します。

SINCE 2026