class: title, smokescreen, shelf, no-footer # 色づかないWorld Wide Webの昨日から<br><small>- HTMLとCGI -</small> <div class=footnote> <small><small> <div class="white"> "Night cityscape in Nagasaki - view from near the mouth of Urakami River (2016-04-09 by Eiji Kikuta @Pixabay 1342591).jpg" by Eiji Kikuta (AG2016) from Sendai, Japan is marked with CC0 1.0. </div> </small></small> </div> <img src="/images/background/Night_cityscape_in_Nagasaki.jpg"> --- name: index class: compact # HTMLとCGIのしくみ <div class=footnote> <small><small> (脚注1) 「ださい」とか言わないように;-) React,Angular,Vueとかの人は各自で頑ばってほしいですが、 (a)なぜCGI -> Ajax -> SPA と進化する必要があったのか? (b)SPAの裏側で何をしているか、 きちんと説明できますか? </small></small> </div> <small> 1. [HTML](#html)という謎言語(?) - [FORM文とCGI](#html-form) 1. [ホームページの動作原理](#www-internal-homepage) ([WWWのしくみ](../www/)の再掲) 1. [CGIの動作原理](#www-internal-cgi) - FORM文とCGIとWorld Wide Webの動作の対応関係 - 2、3の例: [ファイルアップロード](#www-internal-cgi-example-file-upload)、 [じゃんけん](#www-internal-cgi-example-janken) - 注: CGIの編集をしたら、WWWサーバを再起動する必要があります <br> www.pyは簡単化のため**サーバとCGIが一体**になっているため**再起動が必要**ですが、 これは**例外**で、一般のサーバは再起動しません (なぜならWWWサーバとCGIは別のプログラムだから) - コンテンツの管理(作成・編集方法)については[WWWサーバの管理](../www-adm/)を見てください - コンテンツの編集をしても、WWWサーバをリスタートする必要はありません - 一年生の何かの科目の復習 </small> <!-- ../www/index.md の該当部分とシンクロナイズ BEGIN --> <div class=__replace-begin__www-internal></div> <div class=www-internal-begin></div> --- name: html class: col-2,compact # <small>HTML (HyperText Markup Language) たぶん2.0くらい</small> <div class=footnote> <small><small> (脚注1) さらに謎の書き方をするCSS(Cascading Style Sheets)というのがあってのぉ〜 ウエブデザイナ志望の人は勉強してください;D <br> (脚注2) HTML5ならturing完全なのでプログラミング言語だ! というネタがあります。 宴会芸としては良いネタなので是非だれか:-) </small></small> </div class=footnote> <small><small> ``` <!-- コメントの書き方 --> <HTML> <HEAD> <!-- ヘッダ, 制御情報を書く --> <TITLE> タイトル </TITLE> </HEAD> <!-- ヘッダの終わり --> <BODY> <!-- ここからが本文 --> <H1>このページ</H1> <!-- 大きい文字を使う --> <P>文章 <!-- パラグラフのP, </P>は無くてもOK --> <B>太い文字(BOLD)も</B> 書けます。レンダリング時に スペースや改行は無視されるので好きなだけ入れてOK </BODY> </HTML> <!-- タグのブロックを終える時は"/タグ" --> ``` - HTMLは**マークアップ言語**と言われるのですが、 ブラウザの表示に特化した一種のプログラミング言語と言えます - プログラミング言語という場合、 ふつう**汎用プログラミング言語**を指しています。 いろいろな型の変数、条件文、繰り返し文、関数などがあり、 ユーザが好きなものを作成できるものです。 HTMLは汎用ではないのでプログラミング言語とは普通いわない - 原理主義者にキラワレそうな**グチャグチャの言語**です。 左の例のように、 **構造**を意味するタグ(例: HTML, HEAD, BODY, P, H1)と、 **表記**を変更できるタグ(例: B, H1)が入り乱れています。 本来H1は構造(見出しのレベル)を意味していますが、 これを使うとブラウザ上の文字の大きさが変わったため、 文字の大きさを変えるタグだと思っている人が多い(w) でも、この**簡単なところが、とっつき易くて良かった**わけです! **人のページのコピペも簡単だったし!** - 最近は、 きちんと**HTML(構造)とCSS(見栄え)を分けて書きなさいと五月蝿い**ことを言われます。 とほほ... </small></small> --- name: html class: col-2,compact # HTMLは適当に書いても動くのでOK <div class=footnote> <small><small> (脚注) 本当はダメ(w)ですが、うちらウエブデザイナ屋さんではないし、動作確認時の見栄えなんて、どうでもいい </small></small> </div class=footnote> <small> ``` <!-- タグも何も書かずに、 --> Welcome to 自分のページ <!-- だけでもブラウザは表示してくれます --> ``` <wbr> - うちらは動作確認したいだけなんです - ブラウザが頑張ってくれます - 適当にテキストだけ書いてください - タグなんて一つも要りません - HTMLの授業ではないので、これでいいよね?ね? </small> --- name: html-form class: col-2,compact # HTMLのFORM文とCGI <div class=footnote> <small><small> (脚注) 本当は`"値"`のようにdouble quotationでくくらないといけないのですが、なくてもブラウザが対応してくれます:D </small></small> </div class=footnote> <small><small> <small> ``` <FORM METHOD=POST ACTION="URI"> <INPUT TYPE=text NAME=変数名> <!-- 入力欄 --> <INPUT TYPE=submit> <!-- 送信ボタン --> </FORM> <!-- 終わり --> ``` | タグ名 | 属性 | 例 | 説明 | 備考 | |-------- |--------- |---------------------------------- |---------------------------------- |------------------------------ | | FORM | ACTION | http://api.fml.org/api/upload | URI | | | | METHOD | POST | HTTPメソッドの指定 | HTTPの細かな動作モードの指定 | | | ENCTYPE | multipart/form-data | ファイル送信時には指定 | file upload以外では不要 | | INPUT | TYPE | submit | 送信ボタン | | | | TYPE | text | 文字の入力欄 | | | | TYPE | file | 送信したいファイルの指定 | ファイル[選択]のボタンを生成 | | | NAME | jibun | 変数名 | | | | VALUE | アップロード | 表示する文字 | 必須ではない | </small> - 以下、最低限の必須要素だけ紹介します - **大文字/小文字の区別なし。空白や改行も無視されます** - `<FORM>`タグには、通信先のサーバと通信方法の設定を書きます。終わりの`</FORM>`までが一つのブロックです - **`<INPUT>`タグを書くと、ブラウザは、入力欄や送信ボタンを生成**します - INPUTタグの中には、属性値が書けます。いろいろな属性が指定できます。 いろいろあるのですが、今回の演習で使いそうなモノだけ表に書いておきます - 実はFORM文と無関係に`<INPUT>`タグを書いても入力欄や送信ボタンが画面上に作成されますが、 入力してもクリックしても何も起きません:-) <br> (Javascriptでゴニョゴニョするなら何かできますが、このスライドの範囲を越えるので省略) - **`<FORM>`タグのブロックの中に`<INPUT>`を書けば**、 ブラウザが空気を読んでくれて(?)、 **入力や送信のアクションとFORM文を関連づけ**てくれます </small></small> --- class: img-right,compact # HTMLのFORM文とCGI(図)との対応関係 <div class=footnote> <small><small> (脚注) <B> HTMLに下請けプログラムの設定は登場しません。 下請けはWWWサーバの影に隠れたブラックボックスです。 </B> 下請けの設定をWWWサーバの設定には書く必要があります。 今回の演習のwww.pyはサーバと下請けが一体化しているので特殊なケースです </small></small> </div> ![](../images/www-internal-cgi-form.png) <small><small> ``` <FORM METHOD=POST enctype="multipart/form-data" ACTION=http://api.fml.org/parrot/file/v2> <INPUT TYPE=file NAME=file> <INPUT TYPE=submit VALUE=アップロード> </FORM> ``` - **`ACTION=URI`のURI部分は給仕さん(WWWサーバ)のURI**になります。 ふつう**URIは処理内容ごとに異なります** - 図には`<INPUT>`の対応関係も書いてあります - `<INPUT TYPE=FILE NAME=file>`により、ブラウザは入力欄「ファイルを選択」を作成しています - `<INPUT TYPE=submit VALUE=アップロード>`により「アップロード」ボタンを作成しています </small></small> --- name: www-internal-homepage class: img-right,compact # ホームページの動作原理 <div class=footnote> <small><small> (脚注) HTDOCSはカスタマイズの対象です。 <B> HTDOCS = /home/admin/htdocs </B> と設定すれば、 <B> ユーザが個人的に保守できる </B> コンテンツに出来ます。 演習で使うwww.pyは、 厳密なもの(<B>本気で運用するサーバ)ではない</B>ので、 これで十分でしょう。 なお、 本物のWWWサーバの場合は、もっと厳密なユーザ権限の制御をしています (e.g. Apacheのmod_userdirやsuexecなどを勉強しましょう) </div> </small></small> </div> ![](../images/www-internal-htdocs.png) <small><small> 例: http://api.fml.org/upload/ 1. ブラウザが、 サーバ(`api.fml.org`)に見たいコンテンツ(`/upload/`)のリクエストを送ります 1. サーバはコンテンツを探します <br> **変数HTDOCS(サーバの設定)+URIの場所(`/upload/`)** <br> がコンテンツの場所です。 Linuxの場合 `HTDOCS`変数のデフォルト値は`/var/www/html`が多いので、 ここでも`/var/www/html`と仮定します。 またURIの右端が`/`の場合、ファイル名(index.html)が省略されているとみなします。 よって検索目標のファイルは次のものになります `/var/www/html/upload/index.html` 1. index.htmlの中身をブラウザへ送り返します 1. ブラウザが返されたindex.htmlをレンダリングして表示 </small></small> <div class=www-internal-end></div> <div class=__replace-end__www-internal></div> <!-- ../www/index.md の該当部分とシンクロナイズ END --> --- name: www-internal-cgi class: img-right,compact # CGIの動作原理 <small>- 例:オウム返し -</small> <div class=footnote> <small><small> (脚注) [小芝居編] (1)長崎ちゃんぽんください! (2)コックさん、長崎ちゃんぽん作って!できたよ! (3)お客様、長崎ちゃんぽんです </div> </small></small> </div> ![](../images/www-internal-cgi.png) <small><small> 例: http://api.fml.org/upload/ (前ページの続き) 1. ブラウザが表示した入力欄でファイルを選択し、 アップロードボタンをクリックします 1. サーバは(Unix的に)下請けプログラムを呼び出し、 HTTPで渡されたデータを下請けへ回します。 下請けはCGIという約束事にしたがって、 (アップロードされた)ファイルと付随情報を取り出し、 処理結果をサーバに返します 1. サーバは(お客様の)ブラウザに処理結果をそのまま返す 1. ブラウザは返された処理結果をレンダリングして表示 - この例の下請けは処理結果としてHTML(形式の文字列)を返していますが、 第1回のジャンケンAPIやopenBDはJSON形式の文字列を返しています。 ちなみに、今日、モダンなWeb APIという場合、JSON形式でのやりとりが普通です - **下請けは、どんな言語で書いてもOK**。 演習は(機械学習編を考慮して)Pythonですが、 **授業のデモはGo言語**です - www.pyは、演習を簡単にするため、 サーバと下請けが一体化しています(下請けの呼び出し=関数呼び出しです) </small></small> --- name: www-internal-cgi-example-file-upload class: img-right,compact # CGIの動作原理 <small>- 例:(ファイルを)オウム返し -</small> <div class=footnote> <small><small> <small> (脚注) この例は単なるオウム返しなので他サーバとのやりとりがありませんが、 典型的なファイルアップロードの場合、 下請けプログラムがアップロードされたファイルをファイルサーバに保存します。 また、 後で利用しやすくなるように、 ファイルの情報をデータベース化するなどといった処理も必要なはずです </small></small> </small> </div> ![](../images/www-internal-cgi.png) <small><small> 例: http://api.fml.org/upload/ - 下請けプログラム(図(2))は、CGIの約束事にしたがい、ブラウザからアップロードされたファイルを受け取ります - この「オウム返し」の場合、 Go言語で書かれた下請けプログラムが難しい処理を担当しています。 - そのファイルのデータを読み出します - データはバイナリなので、そのままではダメです。 テキストとして扱えるようにする必要があります。 データをアルファベットだけを使うある形式に変換(エンコード)し、 HTML(=長い文字列)を準備します - 作成したHTMLをWWWサーバへ返します(図(2)上向矢) - WWWサーバ(給仕)は、そのHTMLを、そのままブラウザ(顧客,クライアント)へ送ります(図の(3)) - ブラウザは、そのHTMLをレンダリングして結果を表示します(図の(4)) </small></small> --- name: www-internal-cgi-example-janken class: img-right,compact # CGIの動作原理 <small>- 例:ジャンケン -</small> <div class=footnote> <small><small> (脚注) <B> 演習の課題はブラウザ上にJSONが表示されればOKです。 </B> このデモ(http://api.fml.org/janken/)では、 受け取ったJSONを元に、 Javascriptで画面を制御しているのでマシな見栄えのページになっています。 発展課題でJS版に挑戦してくれてもいいですけどね </small></small> </div> ![](../images/www-internal-cgi-janken.png) <small><small> 例: http://api.fml.org/janken/ - Go言語で書かれた下請けプログラム(図(2))は、CGIの約束事にしたがい、ブラウザからデータを受け取ります。 この場合、ユーザのジャンケンの手(数字の0,1,2)のことです - 受け取った値(0,1,2)を変数jibunに入れます - 乱数を使い、コンピュータ側のジャンケンの手(0,1,2)を変数aiteに設定します - ジャンケンの勝敗を計算し、変数kekkaに結果を代入(その結果も0,1,2) - 3変数(jibun,aite,kekka)を使い**JSON形式の文字列を生成** - **JSON文字列をWWWサーバへ返します**(図の(2)上向矢) - WWWサーバ(給仕)は、その文字列を、そのままブラウザ(顧客,クライアント)へ送ります(図の(3)) - ブラウザは、その文字列を表示します(図の(4)) </small></small>