はじめに
ElixirにてCowboyを直接動かすための記事となります。
前回の記事では、リクエストの情報からHTMLの内容の作成を行いました。
今回はcssやJavaScriptなどのスタティックファイルの読み込みを実施し、HTMLから操作できるようにしていきます。
バージョン
使用した言語やライブラリのバージョンは下記となります。
cowboy 1.0のバージョン
Version | |
---|---|
Elixir | 1.3.2 |
Erlang | 19.2 |
Cowboy | 1.0.4 |
cowboy 2.0のバージョン
Version | |
---|---|
Elixir | 1.3.2 |
Erlang | 19.2 |
Cowboy | 2.0.0-pre4 |
リクエスト情報からHTMLを作成
今回はcssやJavaScriptの情報をブラウザに渡す必要があります。
cssやJavaScriptの情報を渡す方法ですが、htmlと同じようにHandlerにて受け渡しを実施するだけで、特に難しいことはありません。
あとはhtmlに記述されているcssやJavaScriptが指定したURLにアクセスしてくれるため取得することができます。
cowboy 1.0の場合
defmodule ElixirCowboyExample.CssHandler do
def init({:tcp, :http}, req, opts) do
{:ok, req, opts}
end
def handle(req, state) do
{method, req} = :cowboy_req.method(req)
#routesで受け渡された :css の内容をparamに設定
{param, req} = :cowboy_req.binding(:css, req)
{:ok, req} = html_example(method, param, req)
{:ok, req, state}
end
def html_example("GET", :undefined, req) do
headers = [{"content-type", "text/css"}]
body = ""
{:ok, resp} = :cowboy_req.reply(404, headers, body, req)
end
#cssを受け渡しするためのHandler
def html_example("GET", param, req) do
headers = [{"content-type", "text/css"}]
# paramに指定されたcssファイル名を取得し、replayにて返信する
{:ok, file} = File.read "priv/static/css/#{param}"
body = file
{:ok, resp} = :cowboy_req.reply(200, headers, body, req)
end
def terminate(_reason, _req, _state) do
:ok
end
end
defmodule ElixirCowboyExample.JavascriptHandler do
def init({:tcp, :http}, req, opts) do
{:ok, req, opts}
end
def handle(req, state) do
{method, req} = :cowboy_req.method(req)
#routesで受け渡された :javascript の内容をparamに設定
{param, req} = :cowboy_req.binding(:javascript, req)
{:ok, req} = html_example(method, param, req)
{:ok, req, state}
end
def html_example("GET", :undefined, req) do
headers = [{"content-type", "text/javascript"}]
body = ""
{:ok, resp} = :cowboy_req.reply(404, headers, body, req)
end
def html_example("GET", param, req) do
headers = [{"content-type", "text/javascript"}]
# paramに指定されたJavaScriptファイル名を取得し、replayにて返信する
{:ok, file} = File.read "priv/static/js/#{param}"
body = file
{:ok, resp} = :cowboy_req.reply(200, headers, body, req)
end
def terminate(_reason, _req, _state) do
:ok
end
end
def run do
# routes に JavaScriptとcssを受け渡しするためのHandlerの設定
routes = [
{"/", ElixirCowboyExample.Handler, []},
{"/dynamic", ElixirCowboyExample.DynamicPageHandler, []},
{"/json", ElixirCowboyExample.JsonHandler, []},
{"/:html", ElixirCowboyExample.Handler, []},
{"/priv/static/js/:javascript", ElixirCowboyExample.JavascriptHandler, []},
{"/priv/static/css/:css", ElixirCowboyExample.CssHandler, []}
]
dispatch = :cowboy_router.compile([{:_, routes}])
opts = [port: 4000]
env = [dispatch: dispatch]
{:ok, _pid} = :cowboy.start_http(:http, 100, opts, [env: env])
end
<html>
<head>
<meta charset=\"utf-8\">
<title>Cowboy Hello!</title>
<script type="text/javascript" src="priv/static/js/main.js"></script>
<link rel="stylesheet" type="text/css" href="priv/static/css/main.css">
</head>
<body>
<h1>Cowboy Hello!!</h1>
<h2>file load test<h2>
<input class="button" type='submit' value='test' onclick="func()">
</body>
</html>
h1{
color:red;
}
.button{
width: 200px;
}
function func(){
window.alert("HELLO WORLD");
}
cowboy 2.0の場合
defmodule ElixirCowboyExample.CssHandler do
def init(req, opts) do
method = :cowboy_req.method(req)
#routesで受け渡された :css の内容をparamに設定
param = :cowboy_req.binding(:css, req)
{:ok, resp} = html_example(method, param, req)
{:ok, resp, opts}
end
def html_example("GET", :undefined, req) do
headers = %{"content-type" => "text/css"}
body = ""
{:ok, resp} = :cowboy_req.reply(404, headers, body, req)
end
def html_example("GET", param, req) do
headers = %{"content-type" => "text/css"}
# paramに指定されたcssファイル名を取得し、replayにて返信する
{:ok, file} = File.read "priv/static/css/#{param}"
body = file
{:ok, resp} = :cowboy_req.reply(200, headers, body, req)
end
end
defmodule ElixirCowboyExample.JavascriptHandler do
def init(req, opts) do
method = :cowboy_req.method(req)
#routesで受け渡された :javascript の内容をparamに設定
param = :cowboy_req.binding(:javascript, req)
{:ok, resp} = html_example(method, param, req)
{:ok, resp, opts}
end
def html_example("GET", :undefined, req) do
headers = %{"content-type" => "text/javascript"}
body = ""
{:ok, resp} = :cowboy_req.reply(404, headers, body, req)
end
def html_example("GET", param, req) do
headers = %{"content-type" => "text/javascript"}
# paramに指定されたJavaScriptファイル名を取得し、replayにて返信する
{:ok, file} = File.read "priv/static/js/#{param}"
body = file
{:ok, resp} = :cowboy_req.reply(200, headers, body, req)
end
end
def run do
# routes に JavaScriptとcssを受け渡しするためのHandlerの設定
routes = [
{"/", ElixirCowboyExample.Handler, []},
{"/dynamic", ElixirCowboyExample.DynamicPageHandler, []},
{"/json", ElixirCowboyExample.JsonHandler, []},
{"/:html", ElixirCowboyExample.Handler, []},
{"/priv/static/js/:javascript", ElixirCowboyExample.JavascriptHandler, []},
{"/priv/static/css/:css", ElixirCowboyExample.CssHandler, []}
]
dispatch = :cowboy_router.compile([{:_, routes}])
opts = [{:port, 4000}]
env = %{dispatch: dispatch}
{:ok, _pid} = :cowboy.start_clear(:http, 100, opts, %{env: env})
end
css、JavaScript、htmlなどのファイルは特に違いはありませんので、cowboy1.0の方を参考にしてください。
記載したコードの実行
コードの記述が完了しましたので、それでは実行していきましょう。
いつも通り iex -S mix
にて cowboy を実行していき、http://localhost:4000/xxx
にアクセスしてみましょう。
下記のようにブラウザの画面に表示されるはずです。
またtestボタンを押下することによって、JavaScriptが動き、ダイアログが表示されます。
最後に
今回はcssやJavaScriptなどのスタティックファイルをHTMLファイルで読み込み使用する方法を実装してみました。
cssやJavaScriptのファイル自体も指定のディレクトリに配置されていれば、Handlerを1つ記載するだけで読み込んで返せば使用することが上のコードからわかりました。
これでHTMLにて実施したい内容はほぼほぼ実施できるのではないでしょうか?
それではまた次回