サーバーとブラウザ上で動くクライアント、それぞれいろいろな選択肢がありますが、ブラウザのために産まれたプログラミング言語「JavaScript」を、サーバーでも使うのが、学習しやすくオススメです。
Windows、Mac、Linux、どの環境の人でも大丈夫。まずは「Deno」をインストール!
(WindowsのPowerShellは「Windowsキー+R」を押して「powershell」と書いてエンター、インストールスクリプト「iwr https://deno.land/x/install/install.ps1 -useb | iex」を貼り付け、エンターで実行!)
公式サイト記載の方法に従ってインストールしたら、コンソールヤコマンドプロンプトを開いて、次のコマンドでバージョン番号が出ることを確認しましょう
$ deno --version deno 1.3.0 v8 8.6.334 typescript 3.9.7
続いて、何かディレクトリを作成し、移動
$ mkdir test $ cd test
そのディレクトリ内に、次の2行だけのプログラムを main.js として保存します
import { Server } from "https://code4sabae.github.io/js/Server.js"; new Server(8881);
実はこれだけでwebサーバープログラムできあがり。
動かす時は deno の run コマンド(-Aでファイルアクセス、ネットアクセスを許可)
$ deno run -A main.js
表示されるアドレス http://localhost:8881/ を開いてみましょう。
「Not Found」と表示されますね。(code4sabae-js は、Serverst で動いてます)
表示する HTML は、static ディレクトリを作成し、その中に index.html を作成します。(test/static/index.html)
<h1>Hello web!</h1>
ブラウザをリロードすると表示されるはず!
web開発の基本は、ブラウザとサーバーとの通信ですが、送受信ともにJSONを使って、すっきりシンプルに作りましょう。
下記のように、Serverクラスを派生した、MyServerクラスに api 関数を用意します。ひとまず受け取ったパスやパラメーターに時間を付けて返すテストします。
import { Server } from "https://code4sabae.github.io/js/Server.js"; class MyServer extends Server { api(path, req) { const time = new Date(); return { path, req, time }; } } new MyServer(8881);
先程動かした Deno のサーバープログラムを Ctrl-C で止めて、上を押してエンター。もう一度実行します。2回目以降は即起動!
http://localhost:8881/api/ を開くと、JSONで「時間」が返ってきます。
次に、index.html を編集して、ブラウザからサーバーへデータを送り、サーバーからのレスポンスを表示してみます。 下記のように、JavaScriptのコードを埋め込みます。今どきJavaScriptは、type="module"!
<!DOCTYPE html> <html><body> <button id="btn">fetchJSON</button><br> <textarea id="ta"></textarea><br> <script type="module"> import { fetchJSON } from "https://code4sabae.github.io/js/fetchJSON.js"; btn.onclick = async () => { const req = { a: 123, b: "abc" }; const res = await fetchJSON("http://localhost:8881/api/test/v1", req); ta.value = JSON.stringify(res); }; </script> </body> </html>
ボタンを押すと、テキストボックスにサーバーからのレスポンスが表示されます!
ブラウザから送られてきた JSON をあれこれ加工すれば、みんなで使うwebサービスが開発できそうですね!
HTML/CSS/JavaScriptに関する復習はこちら → 「JSはじめのいっぽ」
プログラムを止めてもデータは残しておきたい?
データベースを学習するのもいいですが、まずは手っ取り早くファイルに保存しておきましょう。
例えば、JSONデータを保存するには、次のように書きます(参考、builtin@stable - deno doc)
Deno.writeTextFileSync("test.json", JSON.stringify(json));
メモリは多量にあるので、プロトタイピング中はデータをまるっと1ファイルに保存しておき、起動時に読み込むくらいで十分です。
みんなが写真をアップロードできるようにすると、webサービスは楽しくなります!
便利機能を用意しました。選ばれたファイルを自動的にいい感じのサイズにして、サーバーの data ディレクトリにアップロード。
アップロードされた URL を取得して、あれこれ使うことができます。
<!DOCTYPE html> <html><body> <h1>image uploader test</h1> <input id="file1" type="file" name="file1" multiple> <div id="imgc"></div> <br> <button id="btn">get file url</button><br> <textarea id="ta" style="width: 80vw; height: 10em"></textarea><br> <script type="module"> import { ImageUploader } from "https://code4sabae.github.io/js/ImageUploader.js"; const maxwidth = 1200; const maxsize = 1 * 1024 * 1024; const uploadurl = "http://127.0.0.1:8881/data/" //const uploadurl = "/data/" file1.onchange = async e => { for (const file of e.target.files) { const type = file.type; if (!type.startsWith("image/")) { continue; } const imgup = new ImageUploader(uploadurl); imgup.setFile(file, maxwidth, maxsize); imgc.appendChild(imgup); } }; btn.onclick = () => { const urls = []; for (let i = 0; i < imgc.children.length; i++) { urls.push(imgc.children[i].value); } console.log(urls); ta.value = urls.join("\n"); }; </script> <a href="./index.html">top</a><br> </body> </html>
大きすぎる写真は使いづらいので、縦横最大サイズを1024以下または、1MB以下にしています。maxwidth や maxsize で設定可能。
このように、ファイルをまとめて選んで、アップロードできます。手元のサーバー data ディレクトリを確認しましょう。
ファイルアップロードで使う画像を扱うあれこれ(Image, ArrayBuffer, Blob, Canvasなど)や、img-upload タグなどのプログラムも短めなオープンソース。
自分なりに改造するのも歓迎です!(src on GitHub)