ハーバード大学 コンピュータサイエンス講座 CS50 2020 Week8 HTML, CSS, JavaScript

ついにwebページを作れるようになる、の巻。
でも、HTMLとCSSとJavaScriptという3つの言語が混在する怒涛の展開にちょっとついていけてない感…。少しずつ慣れていくしかないのか…?
しかしながら、chromeとかのブラウザの開発者ツールでページのソースコードを見たり、いじれたりするなんて、かなり感動した。

/////////////////////////////////////////////////////////////////////////////

今週はWeek8、ハロウィンの週です。
アメリカン・レパートリー・シアターの皆さんのおかげで、今日は特別な照明とキャラクターが登場する素晴らしいステージになっています。
もちろんキャラクターといえば、先週、皆さんはPsetで初めてFiftyvilleを探検し、行方不明になったゴム製のアヒルを探しました。
そしてありがたいことに、犯人が見つかりました!
誰かが挨拶をしたいと言っています。
(舞台袖から巨大なゴム製のアヒルが現れる)
彼もドレスアップしていますが、だいぶお疲れのようです。

今週はウェブプログラミングの世界に移行します。
というのも、この数週間、私たちが書いたコードのほとんどは、コマンドラインプログラムに焦点を当てていたからです。
しかし、私たちが毎日使っているソフトウェアはラップトップやデスクトップのブラウザやモバイルデバイス、アプリの形をしています。
今日からは、一連の言語とテクノロジーに移行し、先週学んだ手続き型プログラミングの知識やメンタルモデルを、より身近でグラフィカルな領域に適用できるようになります。
これからの数週間はウェブプログラミングに焦点を当て、HTMLやCSS、JavaScriptといった言語を使用してウェブサイトを作成し、更には携帯電話のモバイルアプリケーションやアプリを作成していきます。
しかし、このような話をするためには、これらのwebサイトやwebアプリケーションを実行するためのフレームワークを考える必要があります。
そのためには「インターネット」の問題を考えなければなりません。
そもそもインターネットとは何でしょうか?
私たちは毎日インターネットを利用していますが、ここで会場のみなさんからボランティアを募って、インターネットとは何かを定義してもらいたいと思います。
私たちは今、文字通りインターネットを利用していますが、一歩下がって考えてみると、インターネットとは何でしょうか?
自分より技術的に劣る人や、あまり馴染みのない人には、どのように定義するでしょうか?
ソフィア「情報を取り込み、与えるための、世界中の全てのコンピュータのネットワークです。」
↑完璧ですね。
インターネットはネットワークのネットワークです。
自宅に小さなネットワーク、会社や大学に小さなネットワークや大きなネットワークがあり、それらのネットワークをケーブルや何らかの無線技術を使って相互に接続すると、いわば「ネットワークのネットワーク」であるインターネットができあがります。
インターネットは、今日のすべてのアプリケーションを実行するための、いわばインフラです。
webを使うとき、チャットを使うとき、SlackやZoomなどのビデオ会議を使うとき、あなたはインターネットを使っていますが、インターネットは実際には、あなたから誰かに0と1を送り返すための下位の配管であり、その上にあるアプリケーションはすべて、最終的にはソフトウェアで実装されていると考えてください。
このように、すべてのコンピュータが相互に接続されていると考えれば、グローバルコミュニティとして、A地点からB地点、さらにその先へとデータを転送する方法を決定する必要があるのは当然です。
そこで、インターネット上にはルータと呼ばれるコンピュータが設置されています。
私たちが慣れ親しんでいるデスクトップやラップトップよりも少し大きいかもしれませんが、結局のところ
CPU(Central Processing Unit)と呼ばれるコンピュータの中ですべての思考を行う頭脳、
RAM(Memory)と呼ばれるすべての値を保存する場所、
そしてハードディスクと呼ばれるデータを保存する場所
を備えた同じ種類のデバイスです。
ここに写っているのは、数年前にMITが作成した画像で、米国内のインターネット上で最も重要なアクセスポイントの一部を示しています。
(アメリカ全土の地図上にアクセスポイントとネットワークが張り巡らされている)
ここにある赤い点は、基本的に1つのルータ、または1つの重要な場所を示しており、そこに多くのケーブルが入ってきて、国中のあらゆる場所につながっています。
この話は、最近では海底ケーブルやその他の無線技術、衛星技術などを使って、アメリカをはるかに越えて続いています。
つまり、世界中の様々なコンピュータやネットワークがメッシュ状に相互接続されていて、データがA地点からB地点に行くための様々な経路があるということです。
皆さんからFacebook.comへの、あるいはStanford.eduへの直通ラインは必要ありません。
むしろ、皆さんのデータを左から右へ、あるいは上から下へ、あるいはその他の方向へと中継するルータがたくさんあります。
では、これらはどのように機能するのでしょうか?
今から数十年前、人間はグループで集まり、どのような規格を使用するかを決めなければなりませんでした。
より具体的には、これらのコンピュータがどのようなプロトコルを使用するかです。
プロトコルとは、言語というよりも規約のようなものですよね。
健全な時代には、私とあなたが直接会ったときには、手を差し伸べるかもしれません。そうすると、あなたもすぐに手を差し出すでしょう。そうして、握手が成立します。
それが人間のプロトコルなのです。
私は手を差し伸べることであなたとのコミュニケーションを開始します。
あなたはそのコミュニケーションを、手を伸ばすことで確認します。
そして、やり取りは完了します。
人間のプロトコルはそのようなものです。
コンピュータの世界にも同様のプロトコルがありますが、明らかにすべて0と1です。
最初のコンピュータが0と1のパターンを送信すると、相手のコンピュータは異なる0と1のセットを返信しなければなりません。
これから説明するプロトコルは、この0と1のパターンを標準化したもので、実際にはすべてのメッセージが行き来しています。

インターネットでデータをA地点からB地点に送るために最もよく使われるプロトコルは、TCP/IPと呼ばれるものです。
TCPとIPは2つの独立したプロトコルですが、一緒に使われることが多いため、通常はTCP/IPと一口に言います。
これらの頭文字は、MacやPC、あるいは携帯電話の設定などの際に目にしたことがあるかもしれません。
この言葉は、コンピュータがある地点から別の地点へデータを転送するために使用する、基本的に2つの規則を意味しています。
では、データとは何を意味し、A地点とB地点の間で物を動かすとは何を意味するのでしょうか?
ここでは、昔の封筒に例えて考えてみましょう。
世界の誰かに手紙を送りたいと思ったら、昔の皆さんや私なら、恐らく紙切れを手に取るでしょう。
封筒を手に取り、その紙に手紙を書き、紙を封筒に入れます。メッセージを書いた後の最も重要なステップは、その封筒の宛名を書く事です。
もちろん、現実の世界では、受取人の住所は通常、封筒の中央に書きます。
返送先の住所を封筒の上の隅に書き、それから郵便料金などを記入するかもしれません。
しかし、私たち人間は、すべての郵便システムを通じて、封筒を使用する際の慣習をほぼ標準化しています。
ここで、封筒とそこに入っているメッセージは、情報のパケットを例えています。
これは、コンピュータが最終的に0と1を使って行うことを、物理的に具現化したものです。
そこで、実際にデータを封筒に入れ、封筒に住所を記入し、A地点からB地点に送信するために使用される2つの規則を分けて考えてみましょう。
まずIPについて考えてみましょう。
IPとはInternet Protocolの略で、最近のMacやPC、iPhoneやiPad、Android端末のほとんどは、AppleやGoogleなどによってIPを理解できるように設計されています。
私が昔、握手をするという人間の慣習を教えられたように、これらの企業は、それらのデバイスがすべてIPをサポートするようにソフトウェアを書いています。
IP(インターネット・プロトコル)とは、コンピュータがお互いを識別する方法を標準化したものです。
物理的な人間の世界では、例えば私に封筒を送りたい場合、33 Oxford Street,Cambridge,Massachusetts,02138,USAのハーバード大学コンピュータサイエンス学部宛に書けば良いでしょう。
これは恐らく、キャンパス内のコンピュータ・サイエンス・ビルディングを宛先とする固有の住所で、カリフォルニアや海外のどこかで封筒を投函しても、いくつかのホップや郵便輸送業者などを経由して、最終的にはその特定の住所に届くようになっているでしょう。
コンピュータも同様に、IPアドレスと呼ばれる固有のアドレスを持っています。
Mac、PC、携帯電話などのコンピュータがデータを他のサーバに送信するとき、仮想的な封筒の外側に書き込まれるアドレスは、リモートサーバのIPアドレスです。
例えば、私が皆さんにメッセージを送るとしたら、あなたのIPアドレスを把握します。
そのIPアドレスをこの封筒の外側に仮想的に書くのです。
そして恐らく、その封筒の左上に自分のIPアドレスを書く事になるでしょう。
そして、それをインターネット上に発信するのです。
どういうことでしょうか?
つまり、その封筒を持って、一番近いルータに渡すのです。
家にいるときは、実は自分のルータがあります。
それは、ケーブルモデムやDSLモデムなどに接続する機器です。
ハーバード大学やイェール大学などのキャンパスにいる場合、ハーバード大学やイェール大学は独自のルータを持っているので、あなたのコンピュータはキャンパス内ではデータをそちらに渡すようになっています。
家にいても、スターバックスや空港など世界各地にいても、同様にルータがあります。
皆さんのコンピュータは最寄りのルータがどこにあるかを知っており、ルータの役割は、パケットを目的地に近づけるために左、右、上、下のどの方向に移動させるかを判断することにあります。
しかし、これは鶏と卵の関係のようなものです。
もし私があなたに情報を送りたいなら、あなたのIPアドレスを知る必要がありますが、あなたがどこにいるのかを知るまでは、あなたのIPアドレスを実際に知ることはできません。
そこで、皆さんもご存知かもしれませんが、頭文字をとってDNS(Domain Name System)と呼ばれる別のシステムがあります。
これはインターネット上に展開されている技術で、最近ではMacやPC、携帯電話でもサポートされています。
私たちが一般的にドメイン名や完全修飾ドメイン名と呼んでいるものを、英語のような人間が読める文字から、対応するIPアドレスに変換します。
企業が自社のウェブサイトをIPアドレスの数字で宣伝しないのには理由があります。
誰も覚えられないからです。
その代わりに、Microsoft.comやGoogle.com、NewYorkTimes.comなどの名前で宣伝しています。
DNSとは、MacやPC、電話サポートなどで使われている技術で、人間が読むことのできるアドレス(ドメイン名)を入力すると、DNSはその名前をIPアドレスに変換します。
文字通り、Harvard.eduやYale.eduとウェブブラウザに入力すると、MacやPCは付属のソフトウェアを使ってウェブサーバのIPアドレスを調べ、対応するIPアドレスに変換し、インターネット上に送信する前に、封筒の外側にハーバードやイェールのウェブサーバのIPアドレスを仮想的に書き込んでくれるのです。
これは単なるサービスです。
DNSは、皆さんのISP(インターネット・サービス・プロバイダ)が提供するサービスです。
キャンパスにいれば、ハーバードやイェール、スターバックスにいるときはスターバックスでしょう。
皆さんが空港にいるとき、それは空港です。
家にいるときはベライゾンやコムキャストなどの、インターネット・サービス・プロバイダです。
だから、世界もその技術を使うことにしただけなのです。

次に、もう1つの略語、TCPについて説明します。
TCP(Transmission Control Protocol)は、いくつかの問題を解決するためのものです。
その1つは、インターネット上の個々のサーバが複数のことをできるようになると、かなり便利になるということです。
インターネットには様々な機能があります。
サーバは電子メールをホストすることができます。
ウェブサイトやチャットサーバやビデオ会議のホストにもなります。
つまり、インターネット上で使用できるソフトウェアの機能は、増え続けているのです。
経済的にも管理的にも、1台のサーバで複数のことが同時にできるのは良いことです。
そして、実際にそれは可能です。
コンピュータがこの仮想的な封筒を受け取ると、そのコンピュータ(サーバ)は電子メール、ウェブサイト、チャット、ビデオなど、複数のサービスをサポートしている場合、封筒を見て、追加情報を探します。
その情報とはポート番号(PORT_number)と呼ばれるもので、特定のサービスを表すことが世界で決められている小さな整数です。
例えば、TCPの世界では、何年も前に世界が決めたことですが、私たちのコンピュータは事実上、IPアドレスの後に80という数字を封筒に書いて、これがウェブページへのリクエストであることを示します。HTTPSと呼ばれるものを使った安全なページへのリクエストであれば、封筒の外側に443と書く事になっています。
80 HTTP
443 HTTPS
これについては後ほど詳しく説明します。
また、他の番号もあります。
Eメールには独自の番号があります。
Zoomにも固有の番号があります。
私たちが日常的に利用しているインターネットサービスには、それぞれ固有のTCPポートがあり、企業や個人が1つのサーバで複数のことを行えるようになっていますが、これらの封筒を受け取ると、サーバはそれを見て、「ああ、これは電子メールのリクエストだな」と気づくことができます。
これはウェブページのリクエスト、これはチャットのリクエスト…といった具合です。
TCPは、A地点からB地点にデータを送信する際に、データが失われないようにするためのプロトコルの一部でもあります。
コンピュータには有限のメモリしかないので、文字通り、ルータに何か問題が発生したり、送り手が過負荷になって処理できる量よりも多くのパケットを一度に受信したりすることで、データが失われてしますことがあります。
あまりにも多くのデータを送信すると、インターネットが混雑したり、ビデオがバッファリングされたり、様々な症状が発生する可能性があります。
そこでTCPは、必要に応じてデータを再送する処理も行います。
もしインターネット上でパケットが失われた場合、TCPはMacやPC、携帯電話にもそのデータを再送するように促します。
しかし、インターネットで特筆すべきは、データが必ずしも特定の経路を辿らないことです。
実際、ある人から別の人へ複数のパケットを送る場合、そのパケットは毎回異なるルートを通る可能性があります。
これはバグではなく機能であり、サーバが混雑したり、問題が発生して経路を変更しなければならなくなったりする事態が想定されていることによるものです。
TCP/IPは、他のプロトコルとともに、データが時々この方向に行くかもしれない、また他の場合には別の方向に行くかもしれない、といった問題に対する適応型のソリューションもサポートしています。
これが、インターネットの速度が変動する理由の1つです。
というのも、間にあるルータの種類が異なっていたり、少し負荷がかかっていたりするからです。
そこで、CS50のスタッフの協力を得て、このことを伝えようと考えました。
まずは、ブライアンからお願いします。
誰かが持っているMacやPC、携帯電話のウェブブラウザの役になって、私に猫の写真をリクエストしてくれませんか?
ブライアン「ええ。もちろんです。ウェブサーバであるあなたに猫の写真をお願いするには、あなたにリクエストを送るためのメッセージを送る必要があります。
そこで、リクエストを紙に書いておきます。
そして、そのリクエストを封筒の中に入れます。
そして、その封筒に、先ほど話したすべての情報、特にDNSで調べたあなたのIPアドレスをラベル付けする必要があります。
そして、その封筒を送ります。」
↑いいでしょう。
ブライアンと私は別々の場所にいるので、助けが必要です。
彼と私がお互いに封筒を渡すことはできません。
そこで、Zoomに参加しているCS50のスタッフにも協力してもらって、猫のリクエストを受け取るために、ウェブブラウザ役のブライアンからウェブサーバ役の私に、このリクエストを伝えられないか考えてみましょう。
では、こうしましょう。
チームに参加してもらいましょう。
(Zoom上で画面越しに隣の画面の人に封筒を渡していくパフォーマンス)
オーライ。この封筒を渡してくれたフィリスに感謝します。
今手元にあるのはブライアンが送ってくれたリクエストです。
開けてみると、確かに中には猫の写真を要求するメッセージが入っていますが、これはインターネットでは珍しいことではありません。
もし私がウェブサーバで、実際に猫の写真のアーカイブを持っているとしたら、私は先に進み、その猫の写真でブライアンに返事をするつもりです。
しかし、そのためには、私のハードディスクあるいはコンピュータのどこかで、その猫の写真を探さなければなりません。
ブライアンにこの幸せな猫を送ってあげようと思います。
(笑ったような表情の猫の写真)
この封筒の真ん中にブライアンのIPアドレスを書き、左上に私のIPアドレスを書き、その他必要な個人情報を記入してから、猫を封筒に入れます。
しかし、もちろん、この写真はこの封筒に実際には収まりません。
(写真の方が封筒より大きくて入れられない)
これは実際によくあることです。
コンピュータが大量のデータを送信しようとするとき、それが大きな画像であろうと、さらに大きなビデオファイルであろうと、便宜上、コンピュータは大きなパケットを複数の小さなパケットに分割するのが良いとされています。
実際、「ネット・ニュートラリティ」という言葉や、より専門的な話題として「サービス品質」という言葉を聞いたことがあるかもしれません。
ネット・ニュートラリティとは、簡単に言えば、コンピュータがデータの優先順位を決める際に、どのような判断をすべきか、という問題です。
歴史的には、大きなパケットを小さく切って送信することで、他の人のパケットと混ざって、同じ速度で目的地に到達できる、というのが一般的な考え方です。
余談ですが、ネット・ニュートラリティは、一部の当事者が、より多くの料金を支払っている特定の企業のデータを優先的に利用しようとする動きにも関係しています。
このように、基本的なプリミティブの正しい使い方についても言及しています。
しかし、この大きな画像を封筒に詰め込もうとするのはフェアではありませんので、文字通り画像を半分に引き裂き、パケットを2つに切り分けます。
これを封筒に入れると、より簡単に収まります。
これでブライアンのための情報の1つのパケットができました。
ブライアンのためにもう一つ情報のパケットを用意して、この画像の残り半分をいれます。
しかし、私は何か他のことをしなければならないと思っています。
これをインターネットで公開して、フィリスに渡してブライアンに送り返す前に、この封筒に追加の情報が必要かもしれません。
Toの欄にはブライアンのIPアドレスが入っています。
差出人の欄には私のIPアドレスが入っています。
また、ブライアンのために使うポート番号と自分の返信用のポート番号もメモしておきました。
これらは通常、MacやPCで決定されています。
しかし、もう少し情報が必要な気がします。
この封筒の外側に仮想的に何を書いておけば、意図した通りにデータを受け取ることができるでしょうか?
何か考えはありますか?
ここではTCP/IPの知識は前提としていません。
しかし、もしブライアンが今、2通の封筒を手に入れようとしているとしたら、私は彼にどんな追加データを与えるべきでしょうか?グレッグ?
グレッグ「ブライアンは写真の上と下を混同しているかもしれません。ですから、ブライアンにこれが上でこれが下だということを何らかの形で伝える必要があります。」
↑完璧ですね。
ブライアンには、これらのパケットを組み立て直す順番を知ってもらう必要があります。
そうすれば、例えば実際に猫を正しい方法で手に入れることができ、間違った方法で手に入れる事はありません。
これは2つ目のうちの1つ目、もう一つは2つのうちの2つ目、と識別するための番号です。
ブライアンがどのような順序でパケットを組み立て直すかを知ることができるようにするためです。
さらに重要なことは、万が一、パケットの片方、または両方が紛失したり、途中のルータで破棄されたりした場合に、私とブライアンがそれを回復し、必要に応じてパケット1または2を再送できるようにするための十分な情報がパケットに含まれているということです。
では、早速やってみましょう。
チームの協力を仰ぎましょう。まずはフィリスから。
フィリス、お願いします。
(また封筒がZoomの画面越しに渡されていく)
オーライ。でもこれで目的の半分しか達成できていません。
それでは、いよいよ2つ目のパケットを送信します。
理想的にはこれらのパケットを並行して送信するのですが、それでも別々の経路を辿ることができないわけではありません。
こちらの方が時間がかかるのではないかと心配しています。
さて、どうでしょう。
(また封筒がZoomの画面越しに渡されていく)
素晴らしい。
ブライアン、封筒を開けて組み立て直してくれませんか?
ブライアン「はい。封筒が2通あります。
まず、2通のうち1通目と書いてある方を開けると、猫の上半分が入っていますね。
そして、もう1通の封筒を開けると、2通のうちの2通目と書いてあります。
これは猫の下半分ですね。
これで、猫の全貌が明らかになりました。」
↑素晴らしいですね。
ブライアンをはじめとするチームの皆さん。ありがとうございました。

IPとは、封筒に書かれる内容を標準化するためのプロトコルであり、規約です。
コンピュータがお互いに何かの番号を使って一意に識別するための方法です。
TCPは、いくつかの異なる事柄を管理していますが、その中でも、安全でないwebトラフィックには80、安全なwebトラフィックには443といったサービスの番号付けを行い、データがある地点から別の地点に到達し、特定のサーバ上で実行されている適切なアプリケーションによって処理されることを保証しています。
DNSは、そもそも私たちが使用するものです。
もしブライアンが独自のドメイン名を持っていたら、私のコンピュータは彼のIPアドレスを調べなければなりませんし、逆にブライアンは私のIPアドレスを調べなければなりません。
そうすることで、実際にインターネットを利用している私たち人間は、IPアドレスを覚える必要がなくなります。
これがインターネットであり、A地点からB地点にデータを送ることを可能にしている基本的なインフラです。
ある意味では、これを抽象化して、ある地点から別の地点にデータを送る仕組みと考えることができます。
データをある地点から別の地点に送るという基本的な公共サービスがあると仮定できる限り、その上にソフトウェアや他の言語を構築して、実際に面白いことに利用することができるのです。
しかし、その前に、TCPやIP、DNS、インターネット、ルータなどの新しい用語について、何か質問や不明点があれば教えてください。
グレッグ「情報を切り刻むことで何か問題が生じるのでしょうか?というのも、ある情報は転送に2秒、別の情報は転送に3秒かかることがあるからです。ユーザーにとって何か問題が生じるでしょうか?」
↑本当に良い質問ですね。
これらのパケットの転送には様々な時間がかかります。
私はフィリスの手元にほぼ同時に届くようにしましたが、彼女が2つの異なる方向に渡す必要があったとすると、遅れが生じます。
実際、私たち人間は、パケットがA地点からB地点に到達するのに200ミリ秒以上かかると、遅れに気づき始めます。
遅れが2秒、3秒となると、その時点で皆気づきますが、これは必ずしも問題ではありません。ブライアンは2つ目のパケットを辛抱強く待っていました。
最終的には、人間としての彼、コンピュータとしての彼は、恐らく少し不安になり、5秒、10秒、30秒経ってもパケットが届かなければ、再送するように頼むことになるでしょう。
これらの上限は、通常、コンピュータ上で実行されているソフトウェアによって指定することができますが、その時点で、私たちは確実に異変に気づくでしょう。
いいでしょう。

さて、A地点からB地点にデータを送るという基本的な能力を手に入れたとして、ブライアンが私に送った封筒の中には実際に何が入っているのでしょうか?
また、私がブライアンに送った封筒の中には、猫の写真以外に何が入っているのでしょうか?
そこで、HTTP(HyperText Transfer Protocol)と呼ばれる別の言語、あるいは別のプロトコルの話に移ります。
これは、皆さんが何度も目にしたり、タイプしたりしたことのある略語です。
これはもちろん、URL(Uniform Resource Locators)の頭に表示されるもので、インターネット上でどのウェブサイトや画像を要求するかを決めるために使用するツールです。
つまり、ウェブ(ワールド・ワイド・ウェブ)は、インターネット上で動作する数多くのサービスのひとつに過ぎないのです。
ウェブはウェブページを提供します。
Zoomはビデオ会議を提供してくれます。
その他のツールでは、テキストチャットやボイスチャットなどができます。
つまり、ウェブはインターネット上のアプリケーションに過ぎないのです。
最も人気のあるアプリケーションであることは間違いありませんが、実際には単なるアプリケーションです。
それは、その基盤となる配管を利用したサービスなのです。
HTTPは封筒の内側に入るものを管理するプロトコルです。
TCP/IPは封筒の外側を管理します。
HTTPは、ビデオ会議などではなく、webブラウザとwebサーバの話であることを前提に、封筒の内側を管理します。
HTTPにはいくつかの異なるコマンドがあり、かなり限られた語彙しかありませんが、その中でも知っておくべき重要な用語が2つあります。GETとPOSTです。
GET
POST
これらは文字通り英語の動詞で、HTTPがサポートする2つのコマンドと言ってもいいでしょう。
恐らく、ブライアンが封筒の中に入れた紙には、文字通り「GET cat」などと書かれているでしょう。
POSTは後で紹介するように他の用途でも使われますが、GETが重要な言葉です。
文字通り、ブラウザがサーバに情報を要求したり取得したりするための方法です。
ブライアンが送ってくれた封筒のどこかにはGETという英語が入っていて、そのあとに「cat.jpg」などが入っていたでしょう。
もう少し情報があるかもしれませんが、HTTPの本質は、ブライアンが私に何かを要求し、彼がブラウザで私がサーバだとすると、ブライアンは標準化された動詞GETに取得したいファイルの名前を続けて要求を始めるべきだということです。
では、これをお馴染みのURLの文脈で説明しましょう。
例えば、これはURLの正規のフォーマットです。
https://www.example.com/
いくつかの特徴に注目してみましょう。
まず、httpsです。
web上で見かけることが増えてきましたね。
自分で入力しなくても、ブラウザのアドレスバーに自動的に表示されていることが多いですが、これはブラウザやウェブサーバが追加してくれているからです。
このsは、HTTPのセキュアバージョンであることを意味します。
このセキュリティの話題は来週以降にも出てきます。
しかし、HTTPの文脈では、私とブライアンの間でやり取りされるデータが何らかの方法で暗号化されていることを意味しています。
これはシーザー暗号などよりもはるかに優れています。
数学的にも非常に洗練されています。
しかし、基本的には、「ブライアンは自分が猫を求めていることを知っており」、「ウェブサーバである私は彼が猫を求めていることを知っている」という情報をスクランブルするだけです。
しかし、ルータの役割を果たしていた皆さんやTF(ティーチングフェロー、教育助手)の誰かが、悪意を持って、あるいはお節介で、次のスタッフに渡さずに封筒を開けてしまったとしても、封筒の中に何が入っているのか理解できないでしょう。
なぜなら、シーザー暗号などと同様、ランダムに見える0と1しか書かれていないからです。
つまり、httpsは、これらのパケットの内容が暗号化されていることを意味します。
これらのURLについて、他に注目すべき点はあるでしょうか?
example.com
これはドメイン名と呼ばれているものです。
ほとんどの人がドメイン名とは何かを知っていると思いますが、それは通常、「….…」というフレーズです。
example.comはもちろんここでの例ですが、Harvard.eduやYale.eduなど、最近では何百万ものドメイン名があります。
その最後にあるのが、一般的にトップレベルドメイン(TLD)と呼ばれるものです。
com
これは、歴史的には、あなたが訪れようとしているウェブサイトの種類を表していました。
.comは商用、.eduは教育用を意味していました。
.netは何かのネットワーク、.orgは組織を意味しました。
今ではもうそのようなことはありません。
実際、最近では何百、何千ものトップレベルドメインが存在し、ドメインを購入することで物事を分類しようとしていますが、これらのトップレベルドメインのほとんどには厳しいルールはありません。
.eduを使うには、認定された教育機関でなければなりません。
.milを使うには、米軍に所属していなければなりません。
イギリスの.uk、日本の.jpなど、2文字の国別コードのTLDを持つ他の国でも同じような制約があります。
それぞれの国が適切と考える標準化を行うのは自由です。
しかし、誰でも.com、.org、.net、.us、その他たくさんの種類のTLDを購入することができます。
Wikipediaを見れば、ほぼ網羅的なリストを見ることができます。
これはウェブサイトの種類を分類するためのものです。
それに加えて、一般的にホスト名として知られているプレフィックスがあります。
www
wwwは人間の慣習に過ぎません。
何年か前までは、インターネット上のほとんどのサーバはwww.example.comのような、人間に優しい名前を持っていました。
これはウェブサーバのアドレスであって、メールサーバやチャットサーバではないことを意味していました。
厳密に要求されているわけではありません。
これは単なる人間の慣習です。
私もあなたも、ウェブサイトにアクセスするときには、もうこのアドレスをわざわざ入力することはないでしょう。
しかし、これは歴史的な機能であり、視覚的な手がかり、つまり一般的には、それがどのタイプのサーバであるかを人間が知るための手がかりとなります。
それ以外にも、隠された情報が1つあります。
example.comのホームページを見ようと思ったら、このURLを入力するか、あるいはexample.comと入力してEnterキーを押すと、ブラウザがいわばリダイレクトして、正式なURLに連れて行ってくれるかもしれません。
多くの場合、技術的には特定のファイルを要求しています。
https://www.example.com/index.html
特に言及されていない場合、そのファイル名は通常index.htmlです。
使用している言語やサーバの技術によっては、他のファイル名になることもあります。
しかし、URLの最後に暗黙の了解として、ファイル名が書かれていることがよくあります。
ブライアンはcat.jpgをリクエストしたかもしれませんが、もし彼が猫の写真ではなく、テキストやその他の情報を含む本格的なウェブページをリクエストしていたとしたら、恐らくそこにはindex.htmlのような暗黙のファイル名があるはずです。
これは重要なことです。というのも、この封筒の中を見ると、そこに含まれていなければならない情報が入っているからです。
それでは、HTTPリクエストとその応答のサンプルを見てみましょう。
これは、先ほどブライアンと私、そしてスタッフが実践したことの、より技術的な内容です。
技術的に言えば、ブライアンが私に猫のリクエストを送ったとき、彼はこの封筒の中で、GETというキーワードとcat.jpgのようなものだけでなく、他にもいくつかのことを指定しました。
ここで、猫の話題から離れて話を一般化し、次のように説明してみましょう。
仮想的な封筒であるHTTPリクエストの中身は、もし猫の代わりにデフォルトのホームページが欲しい場合は、文字通りGETの後に/スラッシュをつけたリクエストで、続いてブラウザとサーバが話すべきHTTPのバージョンについて言及します。
GET / HTTP/1.1
Host: www.example.com
1.1はかなり一般的です。
2はかなり、ますます一般的になってきています。
3も既に存在しています。
しかし、プロトコルのバージョンが異なるだけです。
人間が握手をする意味を洗練させてきたようなものです。
これらのバージョンのプロトコルは時間とともに進化します。
しかし、私がexample.comだけでなく、Harvard.eduやYale.eduをもサポートする特別なサーバだった場合のために、「Host:www.example.com」のような行もあります。
最近の企業では、複数のウェブサイトや複数のドメインを同じサーバでホスティングすることが可能になっています。
封筒の中にあるこの小さな手がかりは、example.comやHarvard.edu、Yale.eduが物理的に同じサーバを共有している場合に、それらに確実に届くようにします。
より具体的には、リクエストは次のようになります。
GET /index.html HTTP/1.1
Host:www.example.com
単にデフォルトのホームページを要求しているのではなく、特定のファイルを要求している場合は、例えば/index.htmlのように表示されます。
私の応答はどのようなものでしょうか?
私はブライアンの封筒を手に入れました。
今度は自分の封筒を使って返信してみます。
私の封筒の中には、確かに猫の断片が入っていますが、プロトコルに従って、いくつかの追加情報も入っています。
私の反応は…人間の世界と同じように、ブライアンが握手を求めてきたら、私は手を差し伸べるかもしれません。
HTTP/1.1 200 OK
Content-Type: text/html

HTTP/1.1は、私がどのバージョンを話しているかをブラウザに思い出させるためのもので、次にステータスコードである数字、そしてOKのような略式の要約が続きます。
「200 OK」は、「了解しました。猫を見つけました。この封筒の中に、一枚一枚入っています。」という意味です。
また、封筒の中にはコンテンツのタイプも記載しています。
ウェブページであれば、text/htmlと記入します。
jpgであれば、代わりにimage/jpgとするかもしれません。
そして、世界中の様々なファイルフォーマットに対応した、異なるコンテンツタイプ(別称:ラインタイプ)があります。
ブラウザが情報を要求し、サーバが要求された情報を応答するというような単純なやり取りであるとは限りません。
時にはユーザーが間違った場所に行ってしまうこともあります。
例えば、あるブラウザがwww.Harvard.eduにアクセスしたとすると、最初のレスポンスは必ずしもOKではないかもしれません。
GET / HTTP/1.1
Host:www.harvard.edu

ステータスコードは200ではないかもしれません。
実際にこのようなことがあります。
ここで、画面上にブラウザのウィンドウを開いて、例えばHarvard.eduにアクセスしてみましょう。
そして、URLバーにhttp://www.harvard.eduと入力し、Enterキーを押します。
(ウェブページが表示される)
さて、ここまではあっという間でしたが、URLバーをクリックすると、chromeによって簡略化されたり短縮されたりしていますが、実際にはどこに行き着いたのかお気づきでしょうか?
(URLがhttpでなくhttpsに変わっている)
どういうわけか、ブラウザは私をhttpにとどめておかなかったのです。
いわば、httpsにリダイレクトされたのです。
これはハーバード大学側の意図的なものでしょう。
私が記事やその他のコンテンツを読んでも、それは私とハーバード大学以外の誰にも関係のないことなので、むしろ安全に訪問してもらいたいのでしょう。
誰にも…間にあるルータにも見られてはならないのです。
ハーバードは私をHTTPからHTTPSにリダイレクトしました。
どうしてそれがわかるのでしょうか?
chrome、edge、Firefox、Safariなどのブラウザには開発者用のツールが組み込まれていて、あるメニューから有効にする必要がありますが、この開発者用ツールは非常に強力で、ユーザーであるあなたや、プログラマであるあなたが、ブラウザやサーバの裏側で何が起きているのかを見て理解することができます。
ここではchromeを使ってみましょう。
「表示view」→「開発者developer」と進み、「開発者ツールDeveloper Tools」を開きます。
気づかなかったかもしれませんが、chromeユーザーであれば、このメニューオプションはずっと前から存在していたはずです。
ですから、自宅で気軽に遊んでみてください。
そして、右上にこのようなものが表示されます。
(画面の右側にウィンドウが表示される)
...のメニューをクリックして、開発者ツールを画面の下に移動します。
そして、ここで「ネットワーク」タブをクリックしてみます。
「ネットワーク」タブをクリックすると、前回のリクエストに関連する情報がたくさん表示されるので、もう一度リクエストしてみます。
URLバーに戻り、先に進んで…念のため、これをシークレットモード(incognite_mode)でやってみましょう。
あなたがどこにいたか、何というユーザー名でログインしたかをブラウザに記憶させたくない場合は、恐らくシークレットモードを使用する習慣があると思います。シークレットモードは開発者ツールとしては非常に強力で、以前のネットワーク閲覧履歴を残さずにブラウザの状態を最初の状態にリセットすることができます。
そこで、開発者ツールを開いたあと、シークレットモードでもう一度やってみます。
http://www.harvard.edu、Enter。
すると、たくさんの情報がウィンドウに表示され、その中にはパフォーマンスを示すチャート情報も含まれています。
グレッグの質問である時間の長さについては、数ミリ秒から1000ミリ秒の間で変化しているリクエストがあることがわかります。
しかし、私が今気にしているのは、この下のかなり難解なリストです。
画面には様々なものが飛び交っていますが、下の方を拡大してみると、左下のこの記述にあるように、harvard.eduにアクセスするだけで70のHTTPリクエストが誘導されています。
(左下に70requestsと表示されている)
その結果、6.8MBの情報が転送されました。(6.8 MB transferred)
合計で11.95秒かかっています。(Finish:11.95s)
グレッグが言うように、これは相対的に見ても遅いですね。
いや、絶対的に見ても遅いと思います。
さて、ここから何が見えてくるでしょうか?
ウェブページにアクセスすると、そこにあるのはテキストが書かれた1つのウェブページだけではありません。
画像や動画、音楽なども含まれているでしょう。
それらはすべて別々にダウンロードされます。
もしブライアンがコースのホームページのような完全なウェブページを求めてきたとしたら、私は1通や2通の封筒ではなく、70通の封筒で答えるかもしれません。
CS50のホームページの場合は、ハーバード大学のホームページを構成する全てのメディアへの応答を含む大量の封筒で回答するかもしれません。
しかし、ここではそのうちの1つ目のリクエストに焦点を当ててみましょう。
chromeの最初の行を見ると、最初にアクセスした場所のリマインダが表示されます。
しかし、ここのステータス欄が301になっていることに気がつきます。
「301 Moved Permanently」です。
200以外にも、ブラウザが何をすべきかを示す数字があることがわかりました。
200はOKという意味で、要求したデータはここにあるという意味です。
301は、「あなたが要求したものは別のURLに永久に移動しました」という意味です。
それでは、この最初の行をクリックしてみましょう。
そうすると、全く別のタブセットがポップアップします。
ここではヘッダHeadersをクリックしてみます。
ここで用語の定義をします。
ブライアンと私はこの封筒の中でHTTPを使って、GET/HTTP/1.1やHost:www.example.comのようなものを書きましたが、これらのテキストの各行はHTTPヘッダと呼ばれています。
封筒の内側にあるテキストの行です。
ここで表示されているのは、封筒の中にあったすべてのヘッダをchromeがまとめたものです。
Request URL:
http://www.harvard.edu/
Request Method:
GET
Status Code:
301 Moved Permanently
Remote Address:
[2a04:4e42:36::645]:80
Referrer Policy:
strict-origin-when-cross-origin
Accept-Ranges:
bytes
Connection:
close
Content-Length:
0
Date:
Fri, 09 Jun 2023 14:28:15 GMT
Location:
https://www.harvard.edu/
Retry-After:
0
Server:
Varnish
Strict-Transport-Security:
max-age=300
Via:
1.1 varnish
X-Cache:
HIT
X-Cache-Hits:
0
X-Served-By:
cache-hnd18725-HND
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding:
gzip, deflate
Accept-Language:
ja
Connection:
keep-alive
Host:
www.harvard.edu
Upgrade-Insecure-Requests:
1
User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36

まず、自分のリクエストヘッダを見てみましょう。
view source(ソースを表示。現在はRaw?)をクリックしてみましょう。
ブラウザがwww.harvard.eduに送った生のリクエストを見ることができます。

GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: ja
Connection: keep-alive
Host: www.harvard.edu
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36

GET / HTTP/1.1、Host:www.harvard.edu、その他にも色々ありますが、ここでは無視します。
しかし、これらはすべてHTTPヘッダです。
ここで上にスクロールして、応答ヘッダ(Response Headers)を見てみましょう。
ハーバード大学から私のラップトップに別の封筒で戻ってきたものです。

HTTP/1.1 301 Moved Permanently
Connection: close
Content-Length: 0
Server: Varnish
Retry-After: 0
Location: https://www.harvard.edu/
Accept-Ranges: bytes
Date: Fri, 09 Jun 2023 14:28:15 GMT
Via: 1.1 varnish
X-Served-By: cache-hnd18725-HND
X-Cache: HIT
X-Cache-Hits: 0
Strict-Transport-Security: max-age=300

HTTP/1.1ですが、200 OKではなく、301 Moved Permanentlyになっています。
これは私のブラウザへのヒントで、「あなたが訪れたURLには何もありません。」と言っています。
代わりに別の場所に移動する必要があります。
どこに行けば良いのかを知るためには、下にスクロールして、このヘッダを見つける必要があります。
レスポンスの3行目がhttps://www.harvard.eduであることに注目してください
つまり、返信されてきた封筒には「我々は安全なバージョンに移行しました」という手がかりが含まれているのです。
そして、この小さなXをクリックしてタブを閉じると、ブラウザが自動的に送信した次のリクエストは、下にスクロールすると、このリクエストURL、https://www.harvard.eduであることがわかります。そして、それに対する応答は確かに200でした。
このように、これはブラウザとサーバがある場所から別の場所に送信するための単純なメカニズムです。
これをもう少し身近なものにしてみましょう。
なぜなら、人間であるあなたは、今日まで301やMoved Permanentlyといったものを目にすることはほとんどなかったからです。
チャットで教えていただきたいのですが、ウェブページと数字に関して、かなり頻繁に、ある数字を見たことがありませんか?
ブライアン「多くの人が404と言っています。私は500と502も見ました。」
↑ええ。404は何年も前に人間が採用したコードで、単に「Not Found」を意味しています。
誤ったURLや、削除された古い猫など、サーバ上にもう存在しない古いURLにアクセスすると、サーバは200 OKではなく404 Not Foundで応答し、ブラウザに何らかのエラーメッセージを表示するように指示します。
奇妙なことに、数年前のブラウザはユーザーフレンドリーではありませんでした。
ブラウザは人間に404、404と伝えるだけで、これは正直言ってあまりユーザーフレンドリーではありません。
しかし、これは結局のところ、何かが間違っていたこと、何かが見つからなかったことを示す、返信封筒の中の小さなヒントなのです。
これらのステータスコードには一覧があり、覚える必要はありませんが、ウェブ・プログラミングに焦点を当てていくうちに、自然といくつかのステータスコードに慣れていくでしょう。
200 OK
301 Moved Permanently
302 Found
304 Not Modified
307 Temporary Redirect
401 Unauthorized
403 Forbidden
404 Not Found
500 Internal Server Error

ユーザーをある場所から別の場所にリダイレクトする方法は他にもあります。
302や307が使えます。
また、効率化のためにサーバが304で応答することがあります。これは基本的に「あなたはすでにその質問をしました」という意味です。
この猫はサーバ上で変更されていません。
あなた自身の猫のコピーを使ってください、という意味です。
つまり、もしブライアンのブラウザが賢ければ、私からダウンロードしたばかりの猫をキャッシュ(CACHE)して記憶しておき、もしブライアンがリロードしたり、同じウェブサイトに戻ってきて再び猫を見たいと思った時に、ウェブサーバである私を煩わせてミリ秒単位の時間を無駄にして別の猫を送るのではなく、彼のブラウザがローカルコピーを読み込むだけです。
304は「猫は同じものです。あなた自身のローカルコピーを使ってください」と言っているだけです。
他にも色々あります。
401や403を見たことがあるかもしれませんが、これは正しくログインしていないことを意味します。
500は悪いことを意味します。
実際、この先2週間のうちに、皆さんはいくつかのHTTP 500エラーを経験することになるでしょう。
それはあなたがコーディングに失敗して、実際にバグのあるpythonコードを書いてしまい、サーバー全体が何をすべきかわからなくなってしまった時になるでしょう。
修正可能で、デバッグの助けにもなりますが、実際、これもよくあることです。
503は、サーバが何らかの形で過負荷になっている可能性があり、サービスが利用できないことを意味します。
他にも色々あります。
このようにして、見る角度を変えてみると、少しは楽しむことができます。
HTTPリクエストを送信すると、何が返ってくるかを見ることができます。
早速やってみましょう。
ボタンをいちいち操作しなくていいように、ブラウザではなく、コマンドラインツールを使ってみましょう。
ここではCurlというプログラムを使ってみます。
Curlの目的はURLに接続することだけです。
そして、ウェブページやコンテンツをわざわざ見せてくれるわけではありません。
コマンドラインの引数に-Iを取ると、HTTPヘッダを表示するだけです。
それでは先に進んで、http://safetyschool.orgを入力します
curl -I http://safetyschool.org
そして、Enterを押します。
これは私のMacがsafetyschool.orgにホームページを要求するGETという動詞を含む1通の動画を送っているところです。
彼らは恐らく、別の封筒で私に返信し、その中には何らかの応答が入っていることでしょう。
多分それは200でしょう。
他の何かかもしれません。
(結果が表示される)

~/ $ curl -I http://safetyschool.org
HTTP/1.1 301 Moved Permanently
Server: Sun-ONE-Web-Server/6.1
Date: Fri, 09 Jun 2023 15:15:41 GMT
Content-length: 122
Content-type: text/html
Location: http://www.yale.edu
Connection: close

(笑)どうやら…失礼、safetyschool.orgは、この301によると、新しい場所www.yale.eduに永久に移動したようです。
すみません。
しかし、実際に我々はこうすることができます。
このURLをコピーして、ブラウザに入ってみましょう。
過去の履歴が残らないように、再びシークレットモードを使います。
(www.safetyschool.orgをchromeに入力すると、イェール大学のホームページに繋がる)
ほら、見た目の効果はヘッダから想像されるのと同じくらいリアルです。
このジョークの面白いところは、インターネット上の誰かが、このジョークのためにsafetyschool.orgというドメイン名に20年くらいお金を払っていて、その結果、あるドメイン名を別のドメイン名にリダイレクトしているだけだということです。
さて、フェアに行きます。
safetyschool.orgからharvardsucks.orgに移行します。これも存在していて、誰かがこのウェブサイトをホストしています。
実際、このURLにアクセスすると…harvardsucks.orgに行ってみましょう。
Enter。
実際にウェブサイト全体を見ることができます。
イェール大学の人達はここで本当に全力を尽くしました。
harvardsucks.orgには、何年か前に行われたハーバード対イェールのフットボールの試合で行われた素晴らしいハックやイタズラの古いYouTubeのビデオがあります。
公平に行きましょう。

これらを基本的なHTTPメッセージに結びつけるのは少々無理がありますが、実際にはすべて、これらの非常にシンプルなプリミティブに関連しています。
もう一つ指摘しておきたいことがあります。
HTTPリクエストの形で、ただのスラッシュ/の代わりに、更に洗練された例を見ることができるかもしれません。
例えば、「/cat.jpg」や「/index.html」を要求する代わりに、?クエスチョンマークや=等号が含まれているかもしれません。
GET / search?q=cats HTTP/1.1
Host:www.google.com

これはMacやPC、携帯電話がgoogle.comに猫の写真を要求するために送る封筒からの抜粋です。
実際に、私のブラウザでこれをやってみましょう。
HTTPSにしてみましょう。
わざわざ安全でないバージョンを使う必要はありません。
https://www.google.com/search?q=catsに明示的にアクセスしてみましょう。
これが人間バージョンのURLでMacはこれを低レベルのメッセージに変換して、仮想的な封筒の中に入れることになります。
では、Enterを押してみましょう。
(Googleでcatsという単語を検索した結果が表示される)
すると、ほら、確かに猫の写真がいっぱい出てきました。あまりうまくいかなかった映画のもっと恐ろしい写真もあります。
つまり、URLのフォーマットを理解すれば、サーバに入力を渡すことができるようになるということです。
そして、ここからが以前の週から今後の週への橋渡しとなります。
これまで私たちがharvard.eduやyale.eduなどのウェブページを訪れたとき、私たちはただ静的なウェブコンテンツを訪れていました。
実際には、get_stringやinput()、あるいは我々が書いたコマンドラインプログラムを使うようなユーザー入力はしていません。
しかし、これらのURLはユーザー入力をサポートしており、それらは標準化されています。
?クエスチョンマークとqのような変数名、そして=等号と「cats」のような単語が表示されているとしたら、それはコマンドラインプログラムがqの値を尋ね、人間がcatsと入力したような場合のウェブ版です。
https://www.google.com/search?q=cats
つまり、URLを使って、実際にウェブサーバに入力を渡す方法があるということです。
実際、あなたがgoogle.comにアクセスしているときには、そのようなことが起こっているのですが、結局のところ、このURLを理解する必要があります。

このインフラの上に独自のソリューションを構築する前に、HTTPやステータスコードなど、これまで見てきたものについて、質問や不明点はありませんか?
サンティアゴ「例えば、ウェブページを公開する場合、なぜドメイン名を購入しなければならないのでしょうか?それは、どこかのサーバでメモリを使っているからでしょうか?」
↑ええ。それは本当に良い質問ですね。
なぜドメイン名を買わなければならないのでしょうか?
正直に言うと、それは資本主義に帰結します。
インターネットを運営するにはゼロではないコストがかかります。
歴史的には非営利団体やボランティアがインターネットの運営を支援してきました。
しかし、インターネットを運用するためには、メインのDNSサーバやその他の機能を運営するためのオーバーヘッドが必要になってきています。
そこで、インターネットレジストラと呼ばれるものがあります。
大学のレジストラのようなもので、基本的にドメイン名を年単位でレンタルすることを目的としています。
実際、ドメイン名を購入しても、それは永久に自分のものではありません。
その代わりに、まず購入費用を支払い、1年、2年、3年ごとなどに更新料を支払うことになります。
数ドルから数百ドル、数千ドルになることもあります。
さらに、ドメイン名のスクワッティング(不法占拠)のように、すごく良い言葉を思いついてドメイン名を購入し、それを欲しがる人が現れた場合、そこに資本主義が働いて、誰かにドメイン名を売る機会になる可能性があります。
しかしそれは、誰がドメイン名を登録できるかを正確に規制し、最終的には好きなだけ無料で登録できるようにすることによって、すべてのドメイン名への価格付けが消滅するよう下降圧力をかけるのに役立つと考えられています。

HTTPだけでなく、TCP、IP、DNSなど、今日学んだ用語について、他に質問や不明点はありますか?
ブライアン「チャットで質問がありました。
複数のパケットをある場所から別の場所に送ろうとした場合、それらは次々と送らなければならないのでしょうか?それともすべてのパケットを同時に送ることができるのでしょうか?」
↑良い質問ですね。
先ほどは人間がZoomを使ってうまく振り付けできるとは思っていませんでしたので、ティーチングフェローには1回に1つのパケットを送ってもらいました。
しかし、コンピュータは通常、これらのパケットをすべて同時に送信します。
次から次へと連続して送られてくるのですが、それがとても速いのです。
偶然にも、同じティーチングフェローをルータとして同じルートをたどるかもしれないし、その時のインターネットの混雑具合や忙しさによって、異なる方向に向かうかもしれません。
順番が狂って届くかもしれませんが、だからこそブライアンは封筒の外側に書かれているシーケンスナンバーを知り、正しい順番に並べ替える必要があるのです。

ブライアン、他に何かありますか?
ブライアン「ルータはどのようにして、特定のデータパケットをどちらに送れば良いかを知るのでしょうか?」
↑本当に良い質問ですね。
ルータはどうやって知っているのでしょうか?
昔は、文字通りハードコードされている場合もありました。
ルータのメモリには、少なくとも2つの列からなるExcelのスプレッドシートが入っていると考えることができます。
1つのIPアドレスで、もう1つは右、左、上、下のように進むべき方向です。
実際のケーブルはその4方向には伸びていませんが、比喩的にそのように考えることができます。
このIPアドレスのデータを受信したらこのケーブルで送れ、このIPアドレスのデータを受信したらこのケーブルで送れ…とルータに伝えています。
そして、これらのケーブルはすべて、同じ都市にある他のルータや異なる都市、海を越えたどこかの別のエンドポイントに繋がっています。
先ほどMITの地図で見たような相互接続を、人間がすべて手動で設定しなければならないとしたら、それはとても苦痛なことです。
そこで、今回の授業では触れませんが、ルータが動的に適応するためのプロトコルが他にも存在します。
つまり、突然、私のパケットがブライアンに届かなくなった場合、私は動的にその周辺をルーティングし始め、ルータは、応答がなかったり、返事が来るまでに時間がかかったりするので、それは良い宛先ではなさそうだと判断するプロトコルがあるのです。
そのため、先ほど説明したスプレッドシートであるルーティングテーブルを動的に変更するかどうかを決定するプロトコルがあります。

いいでしょう。
現在、私たちはインターネットというインフラを持っています。
このインフラでは、封筒の外側にアドレスとポート番号を書くことで、A地点からB地点に情報パケットを送ることができます。
HTTPと呼ばれる別のプロトコルがありますが、これはウェブブラウザとウェブサーバに特化して使用されています。
ビデオ会議やチャットには独自の規約やプロトコルがありますが、情報を取得して要求し、情報を応答するためのメカニズムがあります。
Pset4では猫との付き合い方を知りました。
それがbmpであれ、jpgであれ、何か他のものであれ、それはただのビットの並びですが、私たちはまだ実際のページがどのように見えるかを見ていませんでした。
そして実際に、私がブライアンに送り、彼が私に送った封筒、あるいはハーバードやイェールから戻ってきた封筒の中をもう少し深く見てみると、全く別の言語が出てくるのです。
それ自体はプログラミング言語ではありません。
マークアップ言語と呼ばれるもので、論理よりもむしろ美学のためのものです。
他にもCSS(Cascading Style Sheets)やJavaScriptなど、いくつかの言語が含まれていますが、JavaScriptはきちんとしたプログラミング言語です。
でも、ここで5分間の休憩を取りましょう。
戻ってきたあと、ウェブページそのものを作ることを学びます。

さて、ウェブサイトにアクセスして、ホームページやウェブサイト上の特定のファイルを要求するとき、サーバから返されるHTTPヘッダの下の仮想的な封筒の中には何が入っているのでしょうか?
この言語はHTML(HyperText Markup Language)として知られていますが、実際にはプログラミング言語ではありません。
つまり、ループはなく、条件分岐もありません。
関数も変数もありません。
ただのテキストで、何をどのように表示するかを、上から下へと、左から右へと、かなり厳密にブラウザに伝えます。
では、いくつかの例を見てみましょう。
tags
attributes

HTMLページにはタグや要素と呼ばれるものと、属性という2つの異なる概念が含まれています。
それは何でしょうか?
さて、ここに最もシンプルなウェブページがあります。
<!DOCTYPE html>

<html lang="en">
<head>
<title>
hello, title
</title>
</head>
<body>
hello, body
</body>
</html>

ある種、シンメトリックな方法で構成されているのがわかると思います。
ちゃんとしたプログラミング言語のようにインデントされているものもありますが、ここで行われていることにはシンメトリがあります。
では、ここで見ているものを上から下まで正確に分解してみましょう。

<!DOCTYPE html>

この最初の行は、文書型宣言として知られています。
簡単に言うと、最近のウェブページを作るときは、何があってもこの行をファイルの最初の行にします。
これは、私たちがHTMLの最新バージョン5を使用していることを意味します。
人間がより多くの機能を追加することで、HTMLという言語自体が進化していくので、将来的にはこの行も変わっていくでしょう。
その下にあるのはこれからタグと呼ぶもののペアです。
タグとは<>山括弧で囲まれたもので、HTMLのような単語や簡潔なフレーズで始まり、オプションとして単語や等号、等号の後に続く引用符で囲まれた単語などがあります。
ここで黄色くハイライトされているのが、最初のHTMLタグです。
<html lang="en">
...
</html>
偶然にも、このタグはHTMLタグです。
その仕組みは次のようになっています。
ブラウザは、このようなテキストを含む封筒を受け取ると、最初の行を読み、「OK、このファイルにはHTMLバージョン5が含まれている」と言います。
その後に何が来るでしょうか?
「ああ、これがウェブページの内容だ。ブラウザよ、ここにいくつかのHTMLがあるぞ」と言っているのです。
ここで注目して欲しいのはこの文章の下側です。
このファイルの最後には似たようなタグがありますが、同じ単語「html」の前に/スラッシュがあります。
これが上側のオープンタグに対してクローズタグと呼ばれるものです。
あるいは、上側を開始タグと考えれば、これは終了タグです。
そして、ほとんどのタグは一度開くと最終的には閉じる、という対称性を持っており、理想的には適切な順序で閉じることができます。
注意して欲しいのは、他のものを繰り返す必要はないということです。
タグを閉じるときには、簡潔にタグの名前(htmlなど)を述べるだけです。
</html>
これはつまり、「ブラウザよ、HTMLはこれで終わりだ」という意味です。
さて、その中には何が入っているでしょうか?
この下を見ると、ここには属性と呼ばれるものがあるのがわかります。
<html lang="en">
属性とは、特定のタグにとって特別な意味を持つ、短く簡潔なフレーズのことです。
HTMLという言語のドキュメントを読むと、この特定の属性は、HTMLタグにlang="en"を追加した場合、ブラウザに対して「おい、ブラウザ、ここにHTMLがくるぞ。ところで、このウェブページのコンテンツは英語になるだろう」という手がかりを与える、と書かれています。
世界中のすべての言語には、独自の2桁または3桁のコードがあり、これらを引用符の中に入れることで、ブラウザがそれをどのように解釈するかを正確に標準化することができます。
最近では、ブラウザで翻訳機能を有効にしている場合に便利です。
ページがどの言語で書かれているかがわかるので、自分の話し言葉に翻訳するのに役立ちます。
さて、その下には2組のタグ、つまりheadタグとbodyタグがあります。
これらを同時に取り上げるのは、どちらもHTMLタグの子と考えることができるからです。
<head>
...
</head>
<body>
...
</body>

家系図やある種の階層に例えると、このようになります。
HTMLタグがいわば親のようなものだと考えると、この親にはheadタグとbodyタグという2つの子がいて、それぞれが開いたり閉じたりします。
まず、最初のheadタグについて考えてみましょう。
その中には何があるでしょうか?
その中にあるのがtitleタグで、もうお分かりかもしれませんが、私たちが書いているウェブページのタイトルを表しています。
<head>
<title>
hello, title
</title>
</head>
具体的には、このウェブページのタイトルは、文字通り、そして間抜けですが、「hello, title」となります。
これがこのページのタブに表示されているものです。
少し話を戻して、HTMLタグの2番目の子、いわゆるbodyタグを見てみましょう。
<body>
hello, body
</body>
これはウェブページの大きな長方形の領域でボディやビューポートとも呼ばれます。
そしてここでは、ページの長方形の領域の内容が、文字通りhello,bodyになります。
つまり、これはかなり単純化されたページのHTMLであり、タブのタイトルバーはhello,title、大きな長方形の領域のボディはまさにhello, bodyとなっています。
ここでweek5のように、これをデータ構造と考えることができることを明確に指摘しておきましょう。
封筒の中のテキストは上から下、左から右に読まれるだけですが、ラップトップやデスクトップ、携帯電話上でブラウザが実際に行っていることは、実際にメモリ内にデータ構造を構築することです。
Edgeを開発したMicrosoftやchromeを開発したGoogle、safariを開発したappleは、HTMLを大きな長い文字列のように上下左右に読み、それを解析して、コンピュータのメモリ内にこのようなツリー上のデータ構造を構築します。

		document
		↓
		html
	↓		↓
	head		body
	↓		↓
	title		hello,body
	↓
	hello,title

同じように、皆さんはPset5で、大きなテキストファイルのためのハッシュテーブルをメモリに構築したと思います。
ここには階層がありますね。
ファイル全体をいわゆるドキュメントと考えた場合、このツリーの中にいわばノードを描きます。
その最初で唯一の子がhtmlタグです。
実際、すべてのページはこのhtmlタグから始まらなければなりません。
このタグには先ほど説明したようにそれぞれheadとbodyという2つの子があります。
そして、headにはtitleという子があり、その子にはテキストだけの子があります。
細かいことを言うと、html、head、title、bodyは確かにすべてタグであり、開いたり閉じたりしていることを示すために、これらのノードを意図的に異なる形で描いています。
(一番上のdocumentとテキストだけのノードは丸、その他のタグは四角で囲まれている)
これらの一番下の楕円形は単なるテキストです。
これらはタグの内部ではなく、タグそのものでもありません。
こことここにあるのはただの生のテキストです。
そして、documentノードはランダムなノードです。
HTMLでコメントと呼ばれるものがない限り、通常、感嘆符で始まるのはこのノード(document)だけです。コメントはCやpythonで見た自分用のメモのようなものです。
それらにも同様の構文があります。
さて。
そうは言っても、もしこれが最もシンプルなウェブページだとしたら、どこで作ればいいのでしょうか?
どうやって作ればいいのでしょうか?
MacやPCでText EditやNotepad.exeなどを開いて、これを入力し、コピー&ペーストし、ファイルを保存して、ブラウザで開くこともできます。
しかし、それでは面白くありません。
なぜなら、MacやPCにHTMLファイルを保存しただけでは、そのファイルを閲覧できるのは文字通り世界であなただけになってしまうからです。
ですから、理想的なのは、HTMLを書いて保存できるサーバを用意し、他の人、つまりユーザーや顧客がインターネット経由でそのファイルを訪問できるようにすることです。
ありがたいことに、私たちはCS50 IDEというコードを書くためのウェブベースのツールにアクセスすることができますし、これから書くコードはたまたまHTMLです。
では早速やってみましょう。
CS50 IDEで新しいファイルを開いてみましょう。
これを例えばhello.htmlと呼ぶことにしましょう。
.htmlは既存のファイル拡張子です。先に進んでタイプし直してみましょう。
<!DOCTYPE html>は「やあ、ブラウザ。ここにHTMLバージョン5が来たよ」と言っています。
<html lang="en"></html>
(↑勝手に</html>が付く)
好みによりますが、IDEは考えたことを補完しようとするので、タイプする回数を減らすことができます。
これはますますIDE(Integrated Development Environments)の特徴になりつつあります。
今の場合には約半分に減らすことができています。
では先に進んでheadタグを書いてみましょう。
<head></head>
自動的に閉じられたことに注意してください。
次に、ページのtitleタグを開きます。
<title></title>
これも自動的に閉じられます。
そして先に進み、内容をhello,titleのようにしてみます。
<title>
hello,title
</title>
そして、この下、headタグの外側にあるbodyタグで、hello,bodyとします。
<body>
hello,body
</body>
厳密に言えば、インデントは必要ありません。
もし、もう少し簡潔にして、これだけの行数を使わないようにしたい場合は、それも全く問題ありません。
ある程度までは妥当でしょう。
非常に長いタイトルの場合には、恐らくそれを1行にまとめるべきでしょう。
繰り返しになりますが、これらの詳細は、コンピュータやそれを読んでいるブラウザにとっては重要ではありません。しかし、人間にとっては確実に美しく、読みやすくなります。
というわけで、このファイルを保存しました。
<!DOCTYPE html>

<html lang="en">
<head>
<title>
hello,title
</title>
</head>
<body>
hello,body
</body>
</html>

以前はCならmake、pythonならpythonを使っていましたが、コードを書いたり実行したりするわけではないので、どちらも適用できません。
今度はこのウェブページを見てみたいと思います。
そのためにはどうすればいいでしょうか?
ブラウザが必要ですが、それは既にあります。
もちろん、自分のMacでもchromeでもsafariでも何でも使えます。
しかし、サーバも必要です。
CS50 IDEは、コードを書くためのウェブサーバなので、HTMLを提供するためのウェブサーバとしても使えます。
つまり、少し前に私がウェブサーバの役割を果たした時と同様に、私はIDEに同じ機能、つまり、私がブライアンを待っていたように、ただ聞いて、聞いて、聞いて、誰かのブラウザからHTTPリクエストを受け取ったら、適切なファイルで応答する、という機能を実装する必要があります。
さて、私たちは自分ではウェブサーバを実装しませんでした。
最近では、ウェブサーバは一種のコモディティ(コモディティ(commodity)とは、経済学において、完全または実質的な代替可能性を持つ経済的価値またはサービスである。誰がそれらを生産したのかに関係なく、市場はその商品価値を同等かほぼ同じとして扱う 。鉄鉱石、砂糖、米や小麦といった穀物など、大半のコモディティは原材料、根幹資源、農作物)です。
誰でもダウンロードしたり、お金を払ったりして利用することができます。
実際、IDEにはhttp-serverというシンプルなものが付属しています。
これはIDEにプリインストールされているプログラムです。
これはフリーでオープンソースです。
LinuxやMac、PCでも使用できます。
しかし、IDEにはプリインストールされています。
これを実行すると、不思議なことに、2つ目のウェブサーバが起動します。
IDE自体は既にCS50のウェブサーバ上で動いているので、今度は自分でサーバを動かす必要があるのです。
しかし、他のサーバと区別するために、異なるポートを使用するつもりです。
デフォルトでは、CS50 IDEが使用するポートは8080です。
繰り返しになりますが、デフォルトでは、世界中のほとんどのウェブサーバが、安全でない場合にはポート80を、安全な場合はポート443を使用しています。
しかし、これらのポートは残念ながらCS50 IDE自体が既に使用しており、CS50のウェブサーバ上で既に実行されています。
そこで、同じサーバ、つまりクラウド上の同じコンピュータを使って、他のリクエストを聞きたい場合は、並行して2つ目のウェブサーバを起動し、別のポートで聞くようにします。
自分のアカウント以外ではIDE自体をコントロールできなくても、皆さんが自分のウェブサーバを動かすことができるようにしています。
さて、このホスト名は非常に不可解なものです。
Available on:
https://ide-7659dbd7c8c1458996d9cb4b26885f17-8080.cs50.ws
0cda3813などのランダムなものです。
しかし、最終的にはただのURLに過ぎません。
cs50.xyzで終わっていることに注目してください。
(バージョン違い?こっちは.wsで終わっている)
これは私たちが購入したドメイン名で、CS50 IDE上でウェブサーバを動かすという目的のためだけに使用しています。
これをクリックして、「開く」をクリックすると、先ほどhttpサーバを実行したフォルダ内のすべてのファイルの、かなり難解なリストが表示されます。
少し拡大してみると、これまでに書いたファイルはhello.htmlの1つだけです。
(なんか、今までCS50 IDEで作った他のすべてのファイルも表示されてる…やはりバージョン違い?)
それでは、そのファイルをクリックしてみましょう。
(hello,bodyとだけ表示されたページが開く)
ほら。最初のページ「hello,body」です。
フルスクリーンモードなのでタイトルが見えませんが、先にフルスクリーンモードを解除してみましょう。
(タブのタイトルがhello,titleになってる)
確かに、このページのタブでタイトルを拡大すると、hello,titleとなっています。
さて、一体何が起こったのでしょうか?
たまたま、便利だからという理由でCS50 IDEを使っていたのです。
皆さんも既にアカウントを持っています。
自分たちでウェブサーバを動かして、さっきまで人間がやっていた役割のソフトウェア版を実装しています。
先ほどブライアンがブラウザ役を演じていたように、ブラウザとしてchromeを使っています。
サーバから指示された長いURLをブラウザのバーに表示させると、最後が/hello.htmlになっていることに気がつきます。
https://ide-7659dbd7c8c1458996d9cb4b26885f17-8080.cs50.ws/hello.html
つまり、1つの環境で、ウェブページの提供とウェブページのリクエストを行っているのです。
これは完璧です。実際のソフトウェア開発者が自分のウェブサイトやウェブアプリケーションを構築するときには、このようにするでしょう。
実際のソフトウェア開発者は、自分のウェブサイトやウェブアプリケーションを構築するときに、すべてをローカルに保ち、世界に公開する準備が整うまで作業を続けたいと考えます。
さて、ここで先に進んで、このタブの中でひとつ指摘しておきたいことがあります。
実際、皆さんの中には非常に巧妙に、実際、驚くべきことに、このURLを書き写している人もいます。
.IDEのターミナルウィンドウでHTTPサーバを実行すると、一行ずつリクエストが入ってきているのがわかります。
(ターミナルウィンドウにリクエストが表示されていく)
これはログのようなもので、私のウェブサーバはまだ稼働しています。
実際に同じURLを入力したい人がいれば、ビデオの時間を巻き戻して、今すぐインターネット上の私のhello.htmlファイルにアクセスすることができます。
しかし、これはあくまでもテスト用のものです。
ここでちょっと別のことをしてみましょう。
これから別のファイルを作成して、今度は他のHTMLタグのデモをしてみます。
ここに戻って、私の…ターミナルウィンドウは起動したままにしておきますが、今は出力を気にしないので、先に進んでこれを最小化します。
ここにparagraphs.htmlというファイルを作ります。
そして、HTMLの他の機能を導入できないか考えてみましょう。
先に進んで、先ほどと同じように<!DOCTYPE html>と入力して、英語属性のlangをつけたHTMLタグを作りましょう。
<!DOCTYPE html>
<html lang="en">
</html></html>
(</html>が2つ出てきてしまう)
時々、考えを始めて、考えを終わらせずにいたり、また終わらせようとしたりするので、IDEは混乱します。
それはそれでいいのです。
役に立たせるためには、IDEがやろうとしていることを整理しなければならないかもしれません。
先に進んで<head>タグを開きます。
<head>
<title>paragraphs</title>
</head>
ここにタイトルをつけます。
簡潔にするためにすべて1行にまとめます。
bodyタグを開きます。
<body></body>
これからラテン語のテキストを5段落分タイプして、ここに置くことにします。
<body>
5段落のテキスト
</body>
これはlorem ipsumというテキストで、ラテン語に似ていますが、無意味な文字列です。
そして、ここには5つの段落のテキストがあります。
これは別物ですね。
ただの「hello,body」よりもずっと多くのことが書かれています。
それではこのファイルを保存してみましょう。
ここで別のタブに戻ってみましょう。
リロードをクリックするまで何も変わらないことに注意してください。
リロードするとフォルダの最新の内容が表示されます。
(paragraphs.htmlがリストに追加されている)
そこでparagraphs.htmlをクリックしてみると、ラテン語のようなテキストが5段落分表示されます。
(5段落分の長文が改行なく表示される)
しかし、これはただの1つの巨大で長い段落です。
このバグが何であるか、わかる人はいますか?
チャットで、あるいは手を挙げてでも構いませんが、何か考えはありませんか?
ライアン「少なくとも設定を見る限りでは、HTMLはデフォルトで自動的に行間を空けるようにはなっていないように見えます。
そのため、段落の間にスペースを作らない限り、すべての段落が1つの大きな文字列になってしまいます。」
↑その通りです。
HTMLは、その他のコンピュータ言語と同様に、あなたの言うことを文字通りに受け止め、HTMLの場合はこれらのタグを使って何をすべきかを指示しなければ、代わりにデフォルトの動作をすることになります。
では、実際にCS50 IDEに戻ってみましょう。
ここに別のタグを導入してみましょう。
段落(パラグラフ)タグと呼ばれるタグがあります。
このタグの省略形は、単に<p>です。
IDEは私の考えを補完しようとしますが、すでに段落があるので、私は手動でこれを修正する必要があります。
(<p>と</p>で段落を囲む)
それでは、先に進んでここを開いてみましょう。
先週からずっと、コピー&ペーストは悪いことだと主張してきましたが、HTMLの場合はそうではありません。
HTMLだけでは、ラテン語のような5段落のテキストを作ることはできませんから、この場合はコピー&ペーストが正しい解決策です。
もう1つのタブに戻って、リロードしてみましょう。
指示するまでは何も変わりませんから、普通のウェブサイトをリロードするのと同じように、自分のウェブサイトをリロードしてみましょう。
(段落ごとに改行された文章が表示される)
ほら、ライアンが指摘した問題は、HTMLの段落タグを明示的に使うことで解決しました。
特にpタグを使ったのは、HTMLタグは簡潔なものが多いことを示すためです。
入力する文字数が少なくて済みます。
どうしたらpタグを使えば良いことがわかるでしょうか?
授業や本、ウェブサイトかどこかで学ばなければなりません。
しかし、pythonやC言語の時と同様に、世の中にあるHTMLタグや属性のリストをここで教えようとは思いません。調べればすぐにわかるようにするために、今日は特にコンセプトと基礎に焦点を当てます。

では、早速やってみましょう。
最初から全部やるのではなく、これをコピーして、headings.htmlというファイルをもう1つ作りましょう。
論文を書いたり、本を書いたり読んだりするときには、章の見出しやセクションやサブセクションの見出しを付けることがよくありますが、実際、HTMLでもこれを行うことができます。
H1タグは、最大の見出しタグです。
シンプルにするために、ここではOneとだけ書いておきます。
<h1>One</h1>
ここではh2とし、Twoとします。
<h2>Two</h2>
この下にはh3と書いてThreeとします。
<h3>Three</h3>

ブラウザに戻ってリロードすると、headings.htmlというファイルができています。
(段落ごとに見出しが追加されている。見出しはOneが一番大きく、次第に小さくなっていく)
同じ内容ですが、少し綺麗になっていますよね。
大きくて太い見出し、One、Two、Three…見出しがだんだん小さくなっていることに気づきますが、これは本や学術論文の慣習で、セクションやサブセクション、サブサブセクションがだんだん小さくなっていくのです。
必要に応じてカスタマイズすることもできますが、HTMLでは、このように見出しのようなものも簡単にフォーマットすることができます。
では、HTMLでは他にどんなことができるのでしょうか?
IDEに戻ってみましょう。
時間を節約するために、ここまでの内容をコピーペーストしてみましょう。
そして、例えば、list.htmlというファイルを作ってみましょう。
HTMLでリストを書くのはとても簡単です。
ここでタイトルをlistに変更してみましょう。
ここではfoo、bar、bazのような3つのもののリストを作りたいとします。
これらはコンピュータサイエンスの一般的な用語で、数学のx、y、zのようなプレースホルダが必要な場合に、foo、bar、bazなどを使います。
<body>
foo
bar
baz
</body>
さて、これできれいなリストができました。
他のタブに戻って、ディレクトリのインデックスを見てみましょう。
list.htmlがあります。
これをクリックしてみましょう。
(foo bar bazとしか表示されない)
ほら、ライアンが指摘したのと同じ問題が発生しました。
繰り返しになりますが、ブラウザに「リストを開始して、続けて、終了してください」と杓子定規に伝えなければ、ブラウザはただ一つの大きなテキストの塊を望んでいると解釈するでしょう。
実際にはホワイトスペースが確保されています。
新しい行やタブはすべて単一のスペースに集約されました。
しかし、それは私が望むものではありません。
では、どうすればこれを修正できるでしょうか?
何か追加のタグが必要です。
それにはいくつかのアプローチがあります。
「順序なしリスト」というタグがあります。ul(unordered list)は、順不同のリストという意味です。
<ul></ul>
そしてその中に、li(list item)と呼ばれる子タグを入れることができます。
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
確かに、実際のコンテンツであるfoo,bar,bazよりもIDEによって綺麗にハイライトされたHTMLの赤い文字の方が多くなっています。
しかし、ここに戻ってリロードすると、よりすっきりとした箇条書きのリストが表示されます。
(リストアイテムごとに・が頭にあるリストができている)
<! DOCTYPE html>

<html lang="en">
<head>
<title>list</title>
</head>
<body>
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
</body>
</html>

このコースのウェブサイトでは、内容やインデントなどに箇条書きのリストを多用していますが、ulタグをたくさん使っているだけです。
一方、コンピュータに番号を振ってもらう場合は、1、2、3のようにすることができますが、順番を変えたり、間に何かを追加したりしたい場合は、すぐに面倒になってしまうでしょう。
<li>1.foo</li>
<li>2.bar</li>
<li>3.baz</li>
コンピュータは面倒なことをするのが得意なんですね。
そこで、olを使って、この順序なしリストを順序付きのリストに変えてみましょう。
<ol>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ol>
戻ってリロードすると、ほら、1、2、3と自動的に番号が振られています。
(リストアイテムの頭に1.、2.、3.が付く)
番号付けを気にする必要は全くありません。

さて、ページの構造に関連して、もう一つやってみましょう。
最初のhello.htmlをコピーして、table.htmlというファイルを作ってみましょう。
財務情報やスプレッドシートのような表形式のデータをウェブサイトにレイアウトしたいと思ったら、どうすればいいでしょうか?
タイトルをtableにしましょう。
そして、bodyタグの中にtableタグを導入します。
<body>
<table>

    </table>
</body>

tableタグは、テーブルの行と呼ばれるものを定義しなければならないので、少し複雑です。
そこで、tr(table rows)タグを使います。
そして、テーブル行の中にデータを入れることができます。tdはテーブルデータ(table data)です。
数字の1を入れてみましょう。
そして、先に行って、電話のキーパッドのような、少し馴染みのあるもののモックアップを作ってみましょう。

<body>
    <table>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr>
            <td>4</td>
            <td>5</td>
            <td>6</td>
        </tr>
        <tr>
            <td>7</td>
            <td>8</td>
            <td>9</td>
        </tr>
    </table>    
</body>

123の行、456の行、789の行を作ってみましょう。
そして最後に、キーパッドに相当するものとして、、0、#を入力してみましょう。
<tr>
<td></td>
<td>0</td>
<td>#</td>
</tr>
これを保存して、別のブラウザのタブに移動し、table.htmlを開くと、昔の携帯電話のキーパッドのようなものが見えます。

1 2 3
4 5 6
7 8 9

  • 0 #

ここには暗黙の行と列のようなものがあります。
やろうと思えば、これらの間や周囲に実際の線や境界線を入れて、もう少し綺麗にすることもできます。
このように、HTMLでは、テーブルの行にtr、その中の列にはtdを使って表形式のデータをレイアウトすることができます。

さて、ここまでの話はとても退屈でテキスト的なもので、私たちが知っているウェブとは全く異なるものでした。
そこで、元に戻って、もう少し面白いことをしてみましょう。
まず、image.htmlというファイルを作ってください。
そして、先ほどと同じように定型文(hello.html)をコピーペーストします。
タイトルをimageに変更します。
そして、ここでは次のようにしてみましょう。
<img src="harvard.jpg">としてみましょう。
(srcはソースsourceのこと)
私のIDEにはハーバード大学の画像が入っていました。
それをそのまま記述してみましょう。
このalt属性を追加してみましょう。ハーバード大学とします。
<img alt="Harvard University" src="harvard.jpg">
これが何を意味するのかは後ほど説明しますが、ここで、2つ目のタグを紹介します。これを使って、タグの動作をカスタマイズする方法を示してみましょう。
先ほどのlang属性は、ブラウザに「ここは英語で書かれたウェブページです」と伝えることで、ウェブページ全体の動作をカスタマイズしました。
一方、ここには2つの属性があります。
altは統合の後に値を持ち、srcも等号の後に値を持ちます。
一重引用符でも二重引用符でもいいのですが、一貫性を持たせる必要があります。
これらの属性はいずれも、キーと値の間に統合を入れる必要があります。
では、どのようにすれば良いのでしょうか?
このファイルを開いてみましょう。
リロードしてみましょう。
IDEから取得したimage.htmlとHarvard.jpgが表示されているはずです。
ほら、image.htmlはハーバード大学の画像です。
これは面白いですね。
このように特定の画像にリンクすることができます。
alt属性の役割は何でしょうか?
alt属性は、新米プログラマにもベテランプログラマにも見落とされがちですが、これはアクセシビリティに関わることです。
すべての人が、他の人と同じように、見たり聞いたり、メディアとインタラクトできるわけではありません。
視覚や聴覚に障害がある人にとってalt属性はそこに何があるかを言葉で示すための非常に強力でシンプルな仕組みです。
また、画面上のテキストを音声で読み上げてくれるソフトウェアがインストールされているスクリーンリーダーを持っている人は、見ているものが何であるかを聞くことができます。
これらのタグの存在は、実際に授業を受けたり、本を読んだり、オンラインリファレンスを見たりすることで初めて知ることができます。
私たちは今、語彙を増やし始めたところです。

更に一歩進んで、もう少し強力で身近なことをやってみましょう。
link.htmlというファイルを作ってみましょう。
そこに最初の内容(hello.html)を貼り付けてみましょう。
タイトルをlinkと改名します。
実際、HyperText Markup Languageはハイパーテキストに関するものですが、これはリンクを意味する難解な言葉です。
ハイパーテキストとは、他の場所にリンクするリンクを持つテキストのことです。
では、ウェブページにリンクを実装するにはどうすれば良いのでしょうか?
まず、このページでは、ハーバード大学への訪問を勧めてみます。
<body>
visit Harvard.
</body>
別のブラウザに戻って、link.htmlを開いてみましょう。
(visit Harvard.としか表示されない)
もちろん、これでは何も出来ません。
visit Harvard.は明らかにテキストなので、クリックすることもできません。
では、どうすればユーザーを目的地に導くことが出来るのでしょうか?
それには別のタグが必要です。
アンカータグと呼ばれるもので、一文字のaで略され、属性はhref、つまりハイパーリファレンスです。
ハイパーリファレンスとは、何にリンクするか、を意味します。
さて、ここではシンプルに考えてみましょう。
すでに作成したimage.htmlというファイルにリンクしてみましょう。
そして、リンクしたい単語は、文字通りHarvardです。
visit <a href="image.html">Harvard</a>.
Harvardの左には<a href="image.html">、その右には</a>クローズタグを置きます。
繰り返しになりますが、タグに属性を付けたからといって、それをクローズタグに重複してコピーペーストする必要はありません。
タグの名前だけを閉じれば十分なのです。
ファイルを保存して、ブラウザに戻ってみましょう。
少しだけ拡大して、リロードしてみましょう。
(visit Harvard.のHarvardのとこだけ下線が引かれて青字になった)
ほら、お馴染みのハイパーリンクです。多くのウェブページで見られるように、実際に下線が引かれているでしょう。
このリンクにカーソルを合わせてクリックすると、ほら、ハーバード大学を見ることができます。
(リンクをクリックするとimage.htmlにリンクする)
実際、フルスクリーンモードを解除して確認すると、visit HarvardのページのURLの末尾はlink.htmlとなっています。
しかし、このリンクをクリックすると、最終的にはimage.htmlにたどり着き、自分のアカウントのファイルを示す相対URLに移動することに気がつきます。
もしかすると、そのファイルの代わりに、ハーバード大学そのものにリンクしたいかもしれません。
Harvard.eduだけでは不十分です。それはURLではありません。
wwwもURLではありません。
httpやhttpsといったプロトコルが必要なのです。
visit <a href="http://www.harvard.edu">Harvard</a>.
このファイルを保存してリロードし、戻ってくると、テキストは全く同じですが、気が付くと、画面の下の方にごく小さな視覚的な手がかりがあって、どこにたどり着くかを教えてくれています。
(下の方にリンク先www.harvard.eduが表示されている)
実際、これをクリックすると、URLバーはIDEの下のlink.htmlのままではないことに気づきます。
実際のHarvard.eduに移動してしまうのです。
ここで注目すべきは、chromeやsafariなどのブラウザは、良くも悪くも、ブラウザのユーザーエクスペリエンス(UX)をますます単純化している、ということです。
(上のバーにはharvard.eduしか表示されていない)
私は文字通りharvard.eduにいるわけではありません。
アドレスバーをクリックすれば実際にどこにいるかがわかります。
(クリックするとhttps://www.が表示される)
これは開発者にとっては最悪です。
通常のユーザーにとってはドメイン名が表示されるだけの方がスッキリするでしょう。
でも、ちょっと探せば、すべての情報は確かにそこにあるのです。
しかし、これにはある種の悪用法があります。
もし、私が多少悪意のあることをしたとしたら、どうでしょう。
例えば、harvardをyaleに変更して、表示するHarvardはそのままにしておくとしたら?
ブラウザに戻ってリロードすると、現時点では紫ではなく青になっているので、見た目が変わっています。
デフォルトでは、紫は以前に行ったことがあるリンク先であることを意味しています。
青は以前に訪れたことがないことを意味します。
しかし、その微妙な違いに気づかなければ、「ああ、ここは私が行きたい大学だ」と思うかもしれません。
しかし、クリックすると、間違った場所に行ってしまいます。
くだらない例ですが、これは悪用される可能性があります。
この非常にシンプルな仕組みを使って、どんなことが思い浮かぶでしょうか?あるいは、どんな脅威が思い浮かぶでしょうか?
そうですね。今や皆さんもウェブページを作る能力があるので、ある場所に行くと言って、実際には別の場所にユーザーを誘導することができてしまいます。
これがどのように悪用されるかわかりますか?
サンティアゴ「ハッカーと呼ばれる人達が、コンピュータに侵入して悪意のあるソフトウェアを挿入するのに使われるのではないでしょうか?それを使って騙すのです。」
↑ええ。「騙す」というのは重要な言葉です。
つまり、私たちのほとんどは、リンクをクリックする前に、さっき私がやったように、リンクの上にカーソルを置いて、本当に正しい場所に行っているのかどうか、非常にパラノイアックに下を見て確認するという習慣がないでしょう。
そして、下に表示されるアドレスさえも偽装することができます。
ユーザーを騙して正しい場所に行っていると思わせ、更にこの動作を上書きすることができます。
フィッシングの被害に遭ったことのある人、あるいは遭いそうになった人もいるかもしれません。
フィッシングとは、サンティアゴが言うように、ソーシャルエンジニアリングによって人間を騙し、実際には意図していないことをさせようとすることです。
「このリンクをクリックしてPayPal.comにアクセスしてください。パスワード、あるいは社会保障番号を確認する必要があります」このようなメールを受け取ることは、最近では非常に一般的になっています。
最近のメールは、単なるテキストではなく、HTMLそのものです。
Gmailでクリック可能なリンクや画像があるメールを見ていると、そのメールには私たちがここで書いているようなHTMLが含まれています。
ユーザーを騙して、実際には意図していない場所に行かせることは簡単にできます。
今日の収穫は、これらのことを行う方法のメカニズムを超えて、あなた自身の個人的なセキュリティを考慮すること、これらのメカニズムがいかに単純で、実際に皆さんを間違った場所に導くことができるかということ、従って、皆さんがウェブサイトに対してどれほど不信感を抱くべきかということです。

少し前に書いたlink.htmlの正しいバージョンでは、"Harvard"という言葉をテキストとするwww.harvard.eduへのリンクがありました。
ここで、ブラウザのデフォルトのリンクのスタイルを上書きしたいとします。
別のタブでlink.htmlを見ると、とてもつまらないものになっています。
デフォルトでは、20年前からそうでしたが、リンクは訪問する際は青くて下線が引かれ、少なくとも一度は訪問した後は紫で下線が引かれ、視覚的な手がかりとなります。
しかし、CS50のサイトを含め、今日のほとんどのウェブサイトでは、ウェブページ上のリンクに異なる色やスタイルを用いています。
下線の有無、色の違い、もしかしたら背景色も異なるかもしれません。
これらのスタイルは、CSSを使って様々な方法で作ることができます。
では、どのようにすれば良いのでしょうか?
先に進んで、例えば、visit Harvard or Yaleなどとしてみましょう。
visit <a href="http://www.harvard.edu">Harvard</a>
or <a href="https//www.yale.edu">Yale</a>.
リロードするとこんな感じになります。
両方とも退屈な紫色になってしまいましたが、これはすでに両方の場所に行ったからです。
そこで、先に進み、ここにstyleタグを追加します。
<head>
<style>
</style>
同じファイルに収めるために、ここでは別のファイルを導入せず、styleタグを使用するようにします。
styleタグをシンプルにするために、例えば、これらのリンクの色を…最初は全部赤、ff0000にしてみましょう。
<head>
<style>
a
{
color:#ff0000
}
</style>
そして、先に進み、それを保存します。
リロードすると、両方のリンクが赤くなり、下線が引かれているのがわかると思います。
下線はあまり好きではないので、これを取り除いてみましょう。
aタグのテキスト装飾(text-decoration)をnoneに変更しましょう。
<head>
<style>
a
{
color:#ff0000;
text-decoration:none;
}
</style>
繰り返しになりますが、これらのプロパティについて知るには、何らかの形で資料を参照する必要があります。
しかし、それは単に語彙力の問題です。
リロードしてみましょう。
下線が消えています。
しかし、いくつかのウェブサイトのように、リンクの上にカーソルを置くことで、リンクにアンダーラインが表示され、より注意を引くことができたら、ちょっと素敵ですよね。
どうすればそんなことができるのでしょうか?
そのためには擬似セレクタと呼ばれるものを使います。
ユーザーがタグの上にカーソルを置いたときだけタグの動作を変更したい場合は、文字通り、タグの名前:hoverと書きます。
<head>
<style>
a
{
color:#ff0000;
text-decoration:none;
}
a:hover
{
text-decoration:underline;
}
</style>
これにより、デフォルトではすべてを赤にして下線を引かないが、ユーザーがホバー(カーソルを上に置く)したときには下線で装飾する、ということになるわけです。
それではブラウザをリロードしてみましょう。
ここにカーソルを持ってくるまではまだ視覚的な変化はありませんが、ほら、最近のウェブサイトらしくなってきましたね。
(リンクの上にカーソルを持っていったときだけ下線が表示される)
さて、リンクが2つとも赤というのはイェールには公平ではないので、リンクの種類によって色を変えてみたらどうでしょう?
ここで、これらのリンクを様々な方法で区別する必要があります。
そのためにクラスを使うこともできます。
しかし、もしHarvardとYaleのリンクが1つずつしかないのであれば、一意に識別した方がいいでしょう。
id="harvard"という属性を追加してみましょう。変数のようなものなのですべて小文字とします。
<body>
visit <a href="http://www.harvard.edu" id="harvard">Harvard</a>
そして、こちらはid="yale"とします。
or <a href="https://www.yale.edu" id="yale">Yale</a>.
</body>
何とでも呼べますが、HarvardとYaleのリンクは一つずつなので、HTMLで属性を追加して、それぞれのリンクを一意に識別するようにしています。
ここで今できることに注目してください。
ここから色を取り除き、代わりに、idがharvardのタグにはff0000の色を、idがyaleのタグには青色になるように0000ffの色を付けることにします。
<style>

         #harvard         {
    	    color:#ff0000;
        }
        
        #yale
        {
    	    color:#0000ff;
        }
     
	a
	{
	    	text-decoration:none;
    	}
	a:hover
		{
    		text-decoration:underline;
	}
	</style>

そして、ここでの新しい記号は#ハッシュ記号です。
CSSの世界では、単語の前の#は固有識別子(id)harvardまたはyaleを意味します。
単語の前の.ドットはクラスを意味し、位置や文字の大きさを指定します。
また、単語の前に#や.などの記号がない場合は、タグを意味します。
というわけで、繰り返しになりますが、いくつかの構文を紹介しました。
プログラミングコードではありませんが、ある種のコードです。
これを保存して、リロードしてみましょう。
これで、ハーバード大学には赤の下線、イェール大学には青の下線が引かれています。これらの条件の下でのみ区別される、より美しいウェブサイトの始まりです。
このように、CSSではウェブページの外観をより正確にコントロールすることができます。

さて、ここでいくつかの点を確認しておきましょう。
最後の例で、ユーザー入力のアイデアに戻ることができないか考えてみましょう。
IDEに戻って、先ほどのhello.htmlからスターターコードを取ってきて、search.htmlという純粋なHTMLの例を最後に作ってみましょう。
タイトルをsearchという名前にして、ページの本文で新しいタグを使うことにします。
HTMLはformタグもサポートしていて、そのformタグはいくつかの属性を取ることができます。その1つがactionアクションです。
そしてこれが、フォームがユーザーを導く場所です。
これについてはこれから説明していきます。
もう1つの属性はmethodで、methodはHTTPに関する動詞を指定します。
ここではgetを使います。
これまで大文字で表示してきましたが、ここでは小文字で表示しています。
<body>
<form action="" method="get">

    </form>
</body>

formタグの中にはいくつかの入力があります。
inputの名前はq、typeはsearchです。
そして、この下には、typeがsubmitで、値がsearchであるもう1つのinputがあります。
これらは少し違います。
<input name="q" type="search">
<input type="submit" value="Search">
厳密には必要ないので、nameはわざと省略しています。
しかし、これで何をしようとしているのでしょうか?
検索エンジンを実装したわけではありません。
今やっているのは、検索エンジンのフロントエンド、google.comのフロントエンドの実装です。
インターネット上のデータを実際に検索するという大変な作業は、Google自身にやってもらうつもりです。
そこで、actionにhttps://www.google.com/searchを指定します。
<body>
<form action="http://www.google.com/search" method="get">

    <input name="q" type="search">
    <input type="submit" value="Search">

    </form>
</body>

ここには、ユーザーが操作できるテキストボックスやボタンなどのフォームがあり、アクションはgetを使ってユーザーにこのURLを送ることになっています。
しかし、このURLには、ブラウザが自動的に1つのHTTPパラメータ、qという変数を追加することになっています。
なぜでしょうか?
以前、google.comにアクセスしたとき、文字通りhttps://www.google.com/search?q=catsへ行くことによって、検索をシミュレートすることができたことを思い出してください。
私は、Googleのソフトウェアエンジニアが、ユーザーの入力をURL経由で受け付けるように設計されていると主張しました。
通常、このような長いURLを「q」で入力して検索することはありません。
それは信じられないほど苦痛でしょう。
私たちは、検索ボックスやフォームに入力するだけです。
ですから、もし私が別のタブでsearch.htmlを表示したとしても、あなたはフォームの美しさにそれほど感動しないでしょう。
(ブラウザでsearch.htmlを開くと、入力フォームとsearchボタンが実装されている)
しかし、何が起こるか見てみましょう。
今のところ、私のURLはsearch.htmlで終わっています。
この入力フォームに、文字通り「cats」のようなものを入力してみます。
Enterキーを押すか、手動で検索ボタンをクリックすると、HTMLフォームを含むウェブページは、GoogleのURLとgetのmethodをもつactionを持っているので、ブラウザはそれを対応するHTTPリクエストに変換し、URLを変更します。
(searchを押すと、Googleでcatsを検索した結果が表示される)
(URLはhttps://www.google.com/search?q=catsになっている)
そして、ユーザーの入力は、ブラウザによって自動的にq=catsというリクエストをURLに付加されます。
猫だけではありません。
私たちは今、とてもシンプルなGoogleの検索エンジンを持っていて、必要に応じて犬も検索できます。
(dogを検索すると同様にGoogleでdogを検索した結果が表示される)
(URLはhttps://www.google.com/search?q=dogsになっている)
ここでは、URLの末尾が「?q=dogs」に変わっていることに注目してください。
つまり、これがウェブの仕組みなのです。
先ほど、インターネットがどのように機能するかについて話しましたが、生のデータ、0と1、情報のパケットをポイントAからポイントBに送るだけです。
ウェブサイトにアクセスして、特定の猫や犬の写真が欲しいだけでなく、猫や犬を検索したいとき、ウェブサイトにログインしたいとき、amazon.comをチェックアウトしたいとき、ユーザーの入力を提供するには、基本的にこのようなHTMLフォームに常に記入しています。
もっと多くの入力項目があるかもしれませんし、もう少し複雑かもしれませんが、amazon.comでもFacebook.comでも、1つ以上の入力項目があるウェブサイトのフォームタグで、Enterキーを押したり、submitやsearchなどのボタンをクリックしたりして送信すると、リクエストがサーバに送信されます。
ふう。
すべてのHTMLタグを紹介したわけではありませんが、これがHTMLのアイデアのすべてです。
オープンタグやクローズタグから成り、中には0個以上の属性を持つものもあります。
このメンタルモデルを理解することで、フォームを介してユーザーの入力をウェブサイトの検索やウェブサーバに送信する仕組みを構築することができます。
ここでもう1つの動詞を紹介しておきます。Googleは検索プログラムのGETしかサポートしていません。
www.google.com/searchではGETしか使えませんが、POSTも非常によく使われます。
実際、POSTは封筒の中に入れることのできるもう1つの動詞です。
POSTはブラウザ内で起こることを変更し、q=catsやq=dogsのようなものがURLに表示されないようにします。
というのも、これは私たちのプライバシーに対するもう1つの脅威だからです。
皆さんがウェブで検索した後に、皆さんの弟や両親がそのブラウザを訪れた場合、彼らはしばしば皆さんのブラウザの履歴全体をスクロールすることができます。
なぜでしょう?
それはGoogleやBingなどで検索したものが、この仕組みのおかげで、文字通りすべてURLに入ってしまうからです。
そして、ユーザーの利便性のために、ブラウザはこれらのURLをすべてキャッシュするか、保存する傾向があります。
同居人や家族がいる場合には、プライバシーを侵害することになります。ウェブサイトへの登録やチェックアウトの際に、ユーザー名やパスワード、クレジットカード番号など、より機密性の高い情報を入力している場合には、特に注意が必要です。
簡単に言うと、POSTはHTTPで使える別な動詞であり、q=catsを隠すことができます。
クレジットカード番号を隠す場合がこれに相当します。
パスワードを隠すということは、例えて言えば、封筒の中に深く入れるということです。
これはURLバーには入りません。もう少し内密にサーバに送信します。

いいでしょう。
たくさんありましたね。
たくさんのタグを一度に紹介しましたが、おかげでユーザーの入力を取り入れることができるようになりました。
HTMLという言語を使ってウェブページを作成する際の考え方や構文、意味合いなどについて、何か質問はありますか?
ブライアン「特にありません。」
↑いいでしょう。

さて、私はこれまでの作業を恥ずかしく思っています。
というのも、これらのページはどれも非常に退屈かつ見劣りするものばかりで、実際のウェブを使用する際に皆さんや私が日々慣れ親しんでいるようなユーザーインターフェースには程遠いものだからです。
そこで、これらのタブを閉じて、ウェブページの構造だけでなく、ウェブページの外観、ウェブページのスタイリングに焦点を当ててみましょう。
そうすれば、色や形、イメージや音を実際に見ることができる、Scratchの世界に近いユーザーインターフェースを再現することができるようになります。
そのためにはCSS(Cascading Style Sheets)という言語が必要です。
これもプログラミング言語ではありませんが、HTMLと組み合わせて使うことで、ページをより美しくスタイリングすることができる追加の言語です。
CSSはプロパティ(properties)と呼ばれるものを使用します。
プロパティは変数に似ていますが、より一般的には、キーと値のペアです。
繰り返しになりますが、このテーマに注目してください。
例えば、2週間前にpythonの辞書を紹介しました。
これはキーと値のペアの集まりで、基本的にはハッシュテーブルの形をしています。
先ほどHTMLの属性を見ました。これも本質的にはキーと値のペアです。
q=catsはキーと値のペア、q=dogsもキーと値のペアです。
CSSにも同じ考え方がありますが、考案した人が異なるため、属性ではなくプロパティと呼んでいます。
しかし、考え方は同じで、語彙が違うだけです。
CSSを使ってHTMLタグに色やフォントサイズ、位置などの異なるプロパティを適用するには、様々な方法があります。
type selectors
class selectors
ID selectors
では、どうすればいいのでしょうか?
CSSを使えば、すでに作成したような「hello,title」や「hello,body」と書かれたHTMLページから始めて、そこにいくつかの属性やタグを追加することで、スタイリングを始めることができます。
実際には、ウェブページのheadタグ内にstyleタグを追加することができます。
<!DOCTYPE html>

<html lang="en">
<head>
<style>

    </style>

    <title>
        hello,title
    </title>
</head>
<body>
    hello,body
</body>

</html>

この図のようにheadの中に入れることもできますが、bodyの他の場所に入れることもできます。
また、別のファイルに入れて、リンクを貼ることもできます。
このように、いくつかの異なるアプローチがあります。
しかしその前に、具体的な例でより現実的なものにしてみましょう。
この新しい言語を実演するために、css.htmlというファイルに新しい列を作ってみましょう。
まず、いつものように生のHTML、つまり<!DOCTYPE html>から始めましょう。
先に行って、<html lang="en">としてみましょう。
そして、ここ(headタグ)ではページの見出し、ページのタイトルを書きます。
タイトルはシンプルにcssとします。
さて、面白いことをしてみましょう。
この言語で利用可能なHTMLタグをもう少し紹介しましょう。
一つはheaderというものです。
ここでは、ジョン・ハーバードとしてみましょう。
<body>
<header>
John Harvard
</header>
</body>
ハーバード大学の創設者であるジョン・ハーバードのホームページを作ろうと思います。
そして、このページのメインセクションを作ります。
<body>
<header>
John Harvard
</header>
<main>
Welcome to my Home page!
</mein>
</body>
「私のホームページへようこそ!」と書いておきます。
そして、この下には、いわゆるフッタがあります。
ここにはcopyright、著作権マーク、John Harvardと書きます。
<body>
<header>
John Harvard
</header>
<main>
Welcome to my Home page!
</mein>
<footer>
Copyright (c) John Harvard
</footer>
</body>

3行の非常にシンプルなウェブページです
そして、ここに3つの新しいHTMLタグがあります。
これも授業や本、オンラインのリファレンスで学ぶしかないと思いますが、header、main、footerというタグがあります。これらは特別なことをするわけではありません。
H1からH6までの見出しタグのように、ものを大きくしたり太くしたりすることはありません。
これらのタグはセマンティックタグと呼ばれるものです。
これらは一般的な段落タグ以上のもので、プログラマやブラウザが「ああ、これはあなたのページのヘッダだな」と認識するのに役立ちます。
これはあなたのページのメイン部分、これがフッタ部分…といった具合に、スクリーンリーダがページ上で何が本当に重要なのかを区別するのに役立ちます。
また、Google翻訳などの翻訳ツールでは、実際に翻訳して欲しい部分、例えばページの主要部分とヘッダやフッタのようなあまり重要でない情報とを区別するのに役立ちます。
以上、3つのHTTPタグを紹介しましたが、これらは段落タグのようなものです。しかし、より具体的な名前を持っています。
さて。
それでは、このファイルを保存してインデックスに戻りましょう。
css.htmlという新しいファイルができています。
これをクリックすると、ほら。
John Harvard
Welcome to my Home page!
Copyright (c) John Harvard
かなり見劣りしますが、書いてある通りになっています。
この内容で3行になっています。
これをスタイリングして、もう少し魅力的なものにしてみましょう。
そのために、style属性を追加してみましょう。
<header style="">
さて、ここからは少し奇妙な話になります。
HTMLとCSSの世界では、実際に2つの言語を混在させることができます。
このような例は以前にもありました。
SQLを内包したpythonのコードを見ました。
今日はHTMLコードの中にCSSが入っているのを見てみましょう。
そこで、この引用符の中に、いわゆるプロパティ、つまりキーと値のペアを入れてみます。
headerのフォントサイズを大きくし、テキストを中央揃えにしてみましょう。
<header style="font-size: large; text-align: center;">
このパターンに注目してください。
これは新しいです。統合ではありません。追加の引用符もありません。
これは、繰り返しになりますが、HTMLとCSSを発明したのが基本的には別な人たちであることによるものです。
font-sizeはCSSのプロパティの名前であり、美的な設定に関するものです。
:コロンはキーと値を分けるもので、この場合の値はlargeです。
largeを選んだのは、ここで利用可能なものの1つだからです。
他にも、small、medium、large、extra largeなどがあります。
また、特定のフォントサイズやピクセルサイズを使用することもできます。
text-alignは、テキストの位置を揃えるものです。
さて、ここでも似たようなことをやってみましょう。
mainタグでは、font-size:medium、text-align:centerとします。
<main style="font-size:medium; text-align:center;">
そして、ここはfooterで、あまり重要ではないので、style="font-size: small;"とします。
<footer style="font-size: small; text-align:center;">
さて、ファイルを保存します。
悲しいことに;セミコロンが復活してしまいました。
厳密にはすべての場所で必要なわけではありませんが、一貫性を保つためにそうしています。
ここでは、キーと他のキーを分離するために、間違いなく必要です。
それではリロードしてみましょう。
(中央揃えで、文字の大きさがタグごとに異なっている)
ほら、ちょっと綺麗になったでしょう。
大したことはありませんが、John Harvardが大きく、Welcome to my home page!が中くらいで、フッタが小さくなっています。
悪くないと思います。
そして、これも綺麗にしておきましょう。
この(c)は必ずしも綺麗ではありません。
私のスクリーンのどこに記号があるのかわかりませんが、ここで先に進み、©と入力してみましょう。
Copyright © John Harvard
これは奇妙ですが、HTMLエンティティと呼ばれるHTMLの機能で、キーボード上にないことが多いが、とにかく表示したい記号を識別する数値コードです。
((C)が©になる)
リロードして拡大してみると、きちんとした著作権マークが表示されていますね。
他にも、キーボードにない記号のためのHTMLエンティティがあります。

さて。
この後はどうすればいいでしょうか?
これは悪くありませんが、不完全のような気がします。
HTMLを見たことがなくても、私がこれまで書いたコードを基に、このデザインの問題点を指摘できる人はいますか?
私はこのデザインが正しいと主張していますが、チャットで遠慮なく言ってください。
デザインを改善することはできますか?
また、以前にコピーペーストは良くないと言いましたが、だからといってHTMLに必要なコピーペーストができないわけではありません。
ブライアン、何か気になることはありますか?
ブライアン「style属性が非常に長くなってきている、と言っている人がいます。」
↑ええ。長くなっていますし、あえて言えば冗長になっています。
フォントサイズが変わっても、text-align:center、text-align:center、
text-align:center…は必要ないように思えますよね。
なぜそんなことを繰り返しているのでしょうか?
しかし、ここでCSSのCが登場します。
CSSとはCascading Style Sheetsの略で、文字通り、これらのプロパティが滝のように流れることを意味します。
そこで、header、main、footerのそれぞれからtext-align:centerを削除してみます。
そして、もう少し賢くなってみましょう。
bodyは親なので、bodyが持つすべてのプロパティは、いわばその子にカスケードすることになり、3か所ではなく1か所でtext-alignを定義することができるのです。
<body style="text-align:center;">
<header style="font-size: large;">
John Harvard
</header>
<main style="font-size:medium;">

	    Welcome to my Home page!
	</main>
	<footer style="font-size: small;">
    	Copyright &#169; John Harvard
	</footer>
</body>

ページをリロードしてみると、ほら、何も変わっていませんが、ブライアンの指摘に従って冗長性を除去したため、ページのデザインは良くなっています。
これはとても良いことですが、一方で少し滑りやすい斜面のようでもあります。
もし、もっと大きなホームページを作りたいと思ったら、もっとたくさんのコンテンツがあるかもしれません。これらのstyle属性があちこちにあると、すぐに混乱してしまします。
現実の世界で、自分よりも優れたアーティストと共同作業をすることが難しくなります。
CS50の最終プロジェクトなどのように、チームで仕事をしている場合、どちらかがHTMLを担当し、どちらかがCSSを担当するのは良いことかもしれません。
もし全く同じファイルを共同で作成しようとしたら、これは大変なことになります。
そこで、これらを考慮に入れて、HTMLとCSSを別々にすることができないか考えてみましょう。
では、どうすればいいのでしょうか?
ここで、これらのstyle属性をすべて取り除いてみましょう。
これらのstyle属性はページが長くなるにつれてメンテナンス性が悪くなります。
そこで、前にみたもう1つのフォーマット、styleタグに移行しましょう。
属性ではありませんが、ウェブページのheadタグの内側に置くことができるタグです。
ここでは、ちょっと変わったことをしてみましょう。
header、main、footerをそれぞれtext-align:center;にしてみましょう。
<style>
header
{
text-align:center;
}
main
{
text-align:center;
}
footer
{
text-align:center;
}
</style>
そして、一貫性を保つために、以前と同様のfont-sizeにします。
<style>
header
{
font-size:large;
text-align:center;
}
main
{
font-size:medium;
text-align:center;
}
footer
{
font-size:small;
text-align:center;
}
</style>
IDEはこれらのキーワードをすべて認識しているわけではありませんが、ここに白や青のキーワードがあっても問題ありません。
ここにはまだ冗長性がありますが、今やっていることに注目してください。
styleタグの中では、CSSセレクタと呼ばれるものを使うことができます。
type selectors
class selectors
ID selectors
...

セレクタには様々な種類がありますが、今見ているのはタイプセレクタと呼ばれるものです。
ちょっと難しい名前ですが、これは、あるタグのすべてのインスタンス、つまり、すべてのheaderタグ、mainタグ、footerタグをstyle化したい場合、文字通り、styleタグの中に、そのタグの名前を入れ、{}中括弧を入れ、更にその{}中括弧の中に、キーと値のペア、;セミコロンで区切られたプロパティを入れるだけです。
私は、より読みやすくするために、これを別の行に表示しています。
見かけ上は何の変化もありません。
ブラウザに戻ってリロードすると、何も変わっていませんが、実際にはページの残りの部分からCSSが切り離され始めています。
しかし、ここにはまだある程度の冗長性があります。
例えばここ(styleタグ)からtext-align:centerを削除して、代わりに本文(bodyタグ)に適用することもできます。

他のタイプのセレクタも使用できます。
1つまたは複数のプロパティを再利用可能な方法で定義して、あらゆる種類のタグに使用したい場合、CSSはclassと呼ばれるものをサポートしています。
これを代わりに行ってみます。
単に、「headerのfont-sizeをlargeにする」という代わりに、CSSでclassと呼ばれるものを導入しようと思います。classでは、.ドットの後にキーワードを続けます。
そして、この最初のプロパティのセットを.large、次のプロパティのセットを.medium、そして次のプロパティのセットを.smallと呼ぶことにします。
<style>
.large
{
font-size:large;
}
.medium
{
font-size:medium;
}
.small
{
font-size:small;
}
</style>
.ドットで始まっているのが少し奇妙ですね。
これは、classと呼ばれる再利用可能なプロパティのセットを定義するときは、キーワードを.ドットで始める、と人間が決めたからです。
そして、もう1つキーワードを与えようと思います。
.centeredはtext-align:centerとします。
.centered
{
text-align:center;
}
これらのclass、.centered、.large、.medium、.smallは、これから私がHTMLタグに適用するまで、まだどれも使用されていません。
それでは、先ほどstyle属性をすべて削除したHTMLにスクロールバックして、classという別の属性を使用してみようと思います。
<header class="centered large">
<main class="centered medium">
<footer class="centered small">
classという属性の中には、スペースで区切られた単語のリストを入れることができます。
厳密に言えば、スペースはいくつあっても良いのですが、それでは見た目が悪いし、スタイル的にも良くないので、スペースは1つで十分です。
これは単に、「おい、ブラウザよ。次のコンテンツにcenteredクラスとmediumクラスを適用しろ」という意味です。
ブラウザに戻ってリロードしても、やはり何も変わりません。私はコードのデザインを変えているだけです。
うまくいけば、デザインを改善することができます。
しかし、ここでも、centeredを何度も使うのは馬鹿げていると言えるでしょう。
この冗長性を取り除きましょう。
bodyタグにcenteredを追加しましょう。
<body class="centered">
少し引き締まりました。
いくつかの属性を再導入しましたが、もし誰かと共同作業しているのであれば、「大きな文字、中くらいの文字、小さな文字のCSSクラスを作ってくれないか」と言うことができます。
私は、皆さんがそれを正しく行うことを前提として、これらの用語やクラスを使用し、CSSでこのようなコードが定義されていることを前提とすることができます。

しかし、ご存知でしょうか?
私はもう一歩先を行くことができます。
皆さんがこの同じファイルに触れる必要はありません。
皆さんと私は独立して仕事ができるのです。
説明しましょう。
先ほど書いたコードをすべてハイライトしてカットしてみましょう。
このstyleタグも全部捨ててしまいましょう。
名前は何でも構いませんが、styles.cssという名前の新しいファイルを作って、そこに貼り付けて保存します。
▼styles.css
.centered
{
text-align:center;
}
.large
{
font-size:large;
}
.medium
{
font-size:medium;
}
.small
{
font-size:small;
}
インデントはもう必要ないので、キーボードショートカット(Shift+Tab)を使ってすべて移動させます。
これは、皆さんが作業しているファイルかもしれません。
皆さんは別のファイルで私のためにこれらのプロパティとクラスをすべて作成します。
もし皆さんと私が共同作業をしているのであれば、私はHTMLタグの中で、linkタグ(styles.cssというハイパーリファレンス値を持ちます)を使うことができます。
▼css.html
<head>
<link href="styles.css" rel="stylesheet">
<title>CSS</title>
</head>
※relはrelationship

さて、ここで注意しなければならないことがあります。
今までは、ウェブページのリンクをlinkタグと呼び、aタグをアンカーリンクとして使っていました。
これは、クリックできるという意味でのリンクではありません。
これは単に、このHTMLファイルをこのCSSファイルにstylesheetという関係(relathonship)でリンクする、という意味です。
stylesheetとは何でしょうか?
それはスタイルのシートです。
それは、プロパティのファイルです。
これらのプロパティは、タイプやクラスの内部にあることもありますし、これから見るようにユニークなIDもあります。
そのためのタイプもあります。
しかし、ここにあるのは、間違いなく最高のデザインえ、かなりコンパクトです。
非常に簡潔です。
(CSS.htmlには)HTMLとHTMLの値しかありませんが、CSSはすべてこの2番目のファイル(styles.css)にあります。
これで、皆さんと私は独立して共同作業ができるようになりました。

それでは、CSSとその応用について、何か質問はありますか?
ここまではCSSの表面をなぞってきたに過ぎませんが、私をからかうために、皆さんはどうしても背景をカラフルにしたいとします。
そこで、CSSファイルのstyles.cssにアクセスしてみますが、クラスだけを使う必要はありません。
例えば、bodyタグの背景色を赤にしてみましょう。
▼styles.css
body
{
background-color:red;
}
ブラウザに戻ってリロードしてみましょう。
(背景が真っ赤になる)
OK。あっという間に醜くなってしまいました。
IDEに戻って、テキストの色を白に変えて、赤をもう少し目立たせてみましょう。
▼styles.css
body
{
background-color:red;
color:white;
}
リロードします。
(文字が白になった)
少しは綺麗になりました。
任意の色に変更できますが、ここではイェールブルーが良いかもしれません。
▼styles.css
body
{
background-color:blue;
color:white;
}
ほら。青になったでしょう。
また、week4のようにしたい場合は、16進数で00ff00にするのはどうでしょうか?
▼styles.css
body
{
background-color:#00ff00;
color:white;
}
もちろん、緑になります。
このように、世の中には実に多くのCSSプロパティが存在します。
繰り返しになりますが、ここではそのアイデアのみに注目しています。
実際にこれらのプロパティを使用する際には、適切な参考文献を参照して、語彙を増やしていけばよいのです。
いいでしょう。
CSSの機能とHTMLとの関係について、何か質問はありますか?
ブライアン「特にありません。」

さて、今日まったくやっていないことの1つがプログラミングです。
そのためには第三の言語であるJavaScriptが必要になります。
このコースでは、過去数週間、サーバサイド・プログラミングと呼ばれるものを使ってきました。
C言語のコードや、サーバ上でpythonのコードを書いたりしてきました。CS50 IDEは本来、クラウド上にあるサーバです。
しかし、その間、あなたは自分のMacやPC、携帯電話を実際には使っていませんでした。それらは高価なディスプレイ、あるいはスクリーンでしかありませんでした。
すべてのコードはバックエンド・サーバ上で書かれ、実行されています。
これでは宝の持ち腐れと言わざるを得ません。最近では誰もが高級なMacやPC、携帯電話を使っているのですから。これらのデバイスにはCPU、RAM、ストレージ容量があるのに、それらの機能を使っていないのはもったいないことです。
私たちはガラスのスクリーンを使って、サーバ上の他の場所にあるものを見ているだけです。
しかし、後で述べるように、JavaScriptを使えば、コードを書いてサーバに保存し、それをユーザーのコンピュータで実行する、いわゆるクライアントサイド・プログラミングが可能になります。
そして、HTTPやCSSのように単にコードを読み込んで情報を表示するのではなく、封筒の奥にあるJavaScriptのコードを読み込んで、ユーザーのMacやPC、携帯電話で実行するのです。
ここからがウェブプログラミングの面白いところです。自分のものではない本格的なコンピュータを自由に使えるようになったわけです。
それでは、ここで5分間の休憩を取ります。戻ってきたら、最後にJavaScriptを見てみましょう。

さて。戻ってきました。
ここからはウェブページを制御したり、ウェブページに追加したり、ユーザーが見るコンテンツを変更したりするためのプログラミング技法を紹介します。
それによって、ウェブサイトを単なる静的なもの、つまり一度書いたらずっと同じように見ることができるものではなく、ユーザーのインタラクションや入力に応じて何らかの形で変化する動的なものにすることができるのです。
ここでは、JavaScriptを導入することで、ページをよりダイナミックにする方法を考えてみましょう。
それでは早速、JavaScriptの構文の一部を紹介しましょう。
素晴らしいことに、JavaScriptは構文的にはCやpython(特にC)によく似ています。しかし、メモリ管理は行いません。
ポインタもありません。
ですから、Cとpythonの中間のような構文になっています。
でも、これでかなり簡単になったはずです。
scratchでcounterという変数を0に初期化したことを思い出してください。
では、JavaScriptで同じことを宣言するにはどうしたらいいでしょうか?
次のようになります。
let counter = 0;
これは、pythonとは全く違います。
Cとも全く違います。文字通り、letというキーワードを使って、それに続く変数を存在させます。
この場合はcounterと呼ばれる変数で、0に設定されています。
厳密に言えばこの;セミコロンは必ずしも必要ではありませんが、一貫性を保つために、ここでは使い続けます。
scratchのように、counterを1ずつインクリメントして変更したいとします。
JavaScriptでは、このように冗長に書く事ができます。
counter = counter + 1;
Cやpythonのように、もう少し簡潔にこのようにすることもできます。
counter += 1;
++も再び使えるようになっています。
counter++;
pythonでは残念ながら使えませんでしたが、JavaScriptでは++が復活しました。

条件分岐のようなものはどうでしょうか?
if x less than y と言いたい場合、JavaScriptでは次のようになります。
if(x < y)
{
}
{}中括弧も戻ってきました。
しかし、アイデアは同じです。
scratchでのif elseはこのようになっていました。
JavaScriptでは次のようになります。
if(x < y)
{
}
else
{
}
Scratchではif else if elseはこのように見えました。
JavaScriptでは次のようになります。よりCに近いと言えます。
if(x < y)
{
}
else if(x > y)
{
}
else
{
}
elifのような変な略語はありません。
文字通りelse ifの繰り返しですが、()括弧と{}中括弧を使っています。
正直なところ、これから数週間の間に挫折しそうになるかもしれませんが、これらは新しい言語を学ぶ上での下らない詳細のようなものです。
記憶はしなければなりません。
どの言語が何であるかを覚えなければなりません。
でも、{}や()にこだわってストレスを感じることはありません。
それらは基本的には重要ではありません。もちろん、コンピュータにとっては重要です。
しかし、この言語の新しい魅力的な機能を紹介している私たちにとっては、知的な意味で重要ではありません。
ところで、forループやwhileループのようなものはどうでしょうか?
C言語と同じように、JavaScriptではwhile true、つまり、任意の式がtrueの間、とすることができます。
while(true)
{
}
何かを3回繰り返したい場合は、C言語とほぼ同じですが、ここではintではなくletを使っています。
for(let i = 0;i < 3; i++)
{
}
JavaScriptではpythonと同様、ゆるやかな型付けがされています。
型はありますが、プログラマであるあなたが型の指定にストレスを感じる必要はありません。コンピュータがそれを理解してくれるからです。
letはキーワードを宣言する方法です。
JavaScriptで変数を宣言する方法は、定数を含めて他にもありますが、今はシンプルに、このキーワードだけに焦点を当ててみましょう。
(HTMLのツリー構造の図)
これがウェブページと、そのツリー表現です。
このツリーは、ページを読み込んだ後、コンピュータがメモリ内で何をしているかを示すメンタルモデルとして役立ちます。
document

html
↓ ↓
head body
↓ ↓
title hello,body

hello,title
しかし、JavaScriptを使えば、このツリーをリアルタイムに変更することができます。
ユーザーが何かをクリックしたとき、何かをドラッグしたとき、何かを入力したとき、JavaScriptを使えば、このツリーをリアルタイムに変化させることができます。
それによってウェブページはもはや静的ではなく、ある状態に固定されたものではなく、ダイナミックに変化する動的なものになるのです。

では、どのようにしてそれを行うのでしょうか?
では、どこにJavaScriptのコードを書けば良いのか、具体的に考えてみましょう。
そのためには、次のようにheadタグ内にscriptタグを追加します。
<!DOCTYPE html>

<html lang="en">
<head>
<script>

    </script>
    
    <title>
        hello,title
    </title>
</head>
<body>
    hello,body
</body>

</html>
厳密に言えば、このようにbodyに記述することもできますが、これらの選択にはいくつかの論理的な意味があります。
また、CSSと同じく、scripts.jsのようなファイルに書き出すこともできます。
<script src="scripts.js"></script>
とはいえ、タグは違います。それはscriptです。
属性も違います。それはsrcです。
外部ファイルを使用している場合は、タグの中に何も入っていないにも関わらず、タグを閉じなければなりません。
これはこのタグを使用する際の現実の一つです。

それでは、実際にJavaScriptでプログラムを書いてみましょう。
IDEに戻ってみましょう。
hello.htmlを使って、インタラクティブにしてみましょう。
hello,bodyと言い続けるのではなく、私と皆さんにちょっとしたことを言わせることができないか考えてみましょう。
このページの本文を変更して、formタグの中で<input id="name" type="text">としてみましょう。
そして、<input type="submit">として、送信ボタンを作りましょう。
<body>
<form>
<input id="name" type="text">
<input type="submit">
</form>
</body>
とてもシンプルですね。
唯一の違いは、一般的なテキストボックスを使うことです。
検索に特化したものではありません。
そして、送信ボタンも一般的なものを用意しました。
その内容は気にしません。
ブラウザに戻ってクリックすると、Google検索の例と同じようなフォームが表示されますが、今度は自分のHTMLファイルでウェブフォームを使ってユーザーと対話します。
ユーザーが自分の名前を入力して「送信」をクリックすると、Googleではなく私のウェブページが、これを入力した人に「Hello,David.」、「Hello,Brian.」と声をかけるようにしたいのです。
ですから、これまでと同じようにフォームを使うつもりはありません。
Googleに送信するつもりはないので、アクションはありません。
他のどこかに送信するわけでもありません。
私は、ブラウザ自体の中で動く、完全にクライアントサイドのコードを書くつもりです。
では、このフォームに何をさせたいのでしょうか?
このフォームが送信されたら、greetという関数を呼び出してほしいのです。
<form onsubmit="greet()">
<input id="name" type="text">
<input type="submit">
</form>
今のところ、ここはちょっと散らかり始めています。
すぐに片付けましょう。
しかし、HTTPにはalt onsubmitという属性があり、その値はそれ自体HTMLではありません。CSSでもありません。
これはJavaScriptのコードです。
greetという関数を呼び出したいと思います。
この関数はまだ存在していませんが、すぐに作ります。
そのためにはどうすればいいでしょうか?
さて、先に進んで、ここにscriptタグを追加します。
<head>
<script>
</script>
</head>
そして、この上でJavaScriptで関数を定義してみましょう。
これはC言語やpythonに少し似ています。
JavaScriptでは文字通りfunctionと言います。
関数の名前を書いて、引数を()括弧で囲みます。
そして、{}中括弧の中で関数を定義します。
function greet()
{
}
ここでは、alert('hello,body')と言ってみようと思います。
シンプルにhello,bodyと出力することにします。
function greet()
{
alert('hello,body')
}
そして、このフォームはデフォルトでは、他のフォームと同様に、通常はサーバに送信されますので、もう1つおまじないを追加します。
onsubmit属性の中で、return false;を指定します。
<form onsubmit="greet(); return false;">
たくさんのパーツが動いているので、話がややこしくなりつつありますが、基本的なことにもう一度集中してください。
この属性はonsubmitです。
ユーザーが送信したときに何をしたいのでしょうか?
greet関数と呼ばれる2行のJavaScriptコードを実行して、falseを返します。
この文脈でのreturn falseは、フォームを送信しないことを意味します。
関数を呼び出しても、フォームをどこにも送信しません。
私はこの関数を、ユーザーと対話するためのクライアントサイドのツールとして使いたいだけです。
サーバやGoogleなどに送信する必要はありません。
先に進み、これを指定してみましょう。
<input id="name" type="text">
このテキストフィールドには意図的にnameというIDを与えましたが、これはこれから使います。
内容を変更したので、ブラウザに行ってリロードしてみましょう。
Davidと入力することもできますが、今のところは無視されるでしょう。
しかし、「送信」をクリックすると、最高のユーザーインターフェースとは言えませんが、画面上に特定のURLからのアラートが表示され、「hello,body」と表示されます。
しかし、私はここでは本当は「hello,David」と言って欲しいのです。
では、どうすればいいのでしょうか?
さて、IDEに戻って、名前は何でも構いませんが、nameという変数を定義してみましょう。
そして、document.querySelector()という特別な関数を使ってみましょう。
function greet()
{
let name = document.querySelector()
alert('hello,body')
}
これはJavaScriptに付属している関数で、任意のHTML要素を選択することができます。
しかし、何らかのセレクタを使って要素を識別する必要があります。
ここで、良くも悪くも、CSSとHTMLとJavaScriptがお互いのアイデアを借り始めるのです。
ユーザーのテキストボックスの値を取得したい場合、"name"のようなユニークなIDを与えれば、CSSの構文であるnameを使って、それを選択することができます。
<input id="name" type="text">
そしてそのHTML要素、いわばタグを選択したら、その中に入って値を取得することができます。
let name = document.querySelector('#name').value;
この構文は、馴染みがあるようでもあり、ないようでもあります。
C言語では、構造体を作るときに.ドット記法を使いました。
pythonではCSVのようなライブラリで.ドット記法を使いました。
今回も似たような使い方をしています。
documentは、ブラウザのJavaScriptに付属する特別なグローバル変数で、ドキュメントやウェブページに関連するすべてのものにアクセスできます。
querySelectorは、GoogleやMicrosoft、Appleが皆さんのために書いてくれたdocumentに付属する関数で、ツリーから1つ以上のノードを識別するため、引用符で囲まれたCSSセレクタを引数に取ります。
今まで使ったことはありませんが、このツリーには名前があります。
私たちが参照しているこのツリーは、技術的にはDOM、つまり、Document Object Modelと呼ばれています。
これは、document、つまりこのグローバル変数が、このDOM、このツリーにアクセスすることができる、ということを言っています。
document.querySelectorを呼び出すと、ブラウザはツリー全体、つまりノードや親、子、孫などのすべてのノードを検索し、nameというユニークな識別子を持つものを探し、そのノードの内側、いわば長方形の内側を探して、人間が入力した値を取得します。
この値を出力するには、昔ながらの連結を使うことになります。
この文字列にnameを追加してみましょう。
function greet()
{
let name = document.querySelector('#name').value;
alert('hello,' + name);
}
二重引用符を使うこともできますし、一重引用符を使うこともできます。
JavaScriptの世界で一貫している限りは問題ありません。
理由はともかく、慣習的に一重引用符を使う傾向があります。
なぜなら、一重引用符なら二重引用符を入力する場合のようにShiftキーを押し続ける必要がなく、ほぼ2倍の速さで入力することができるからです。
ブラウザに戻ってリロードしてみましょう。
もう一度、自分の名前を入力してみましょう。
ほら、「hello,David」になりました。
ユーザーインターフェースは相変わらずお粗末ですが、少なくともダイナミックになりました。
また、誰の名前でも入力できます。
Brianなら、「hello,Brian」になります。

ウェブページの他の部分も変更することができます。
これは単なる実装の問題ですが、ボタンに値を与えることができ、「greet me」のように表示することができます。
<input type="submit" value="Greet me">
ブラウザに戻ってリロードすると、ボタンはGreet meと表示されます。
テキストの入力には「What's your name?」のようにプレースホルダを設定することができ、ファイルを保存してリロードすると、ボックス上のプロンプトがグレーアウトしたテキストとともに表示されます。入力を開始するとテキストは消えます。
<input id="name" placeholder="What's your name?" type="text">
(入力バーにWhat's your name?と表示される)
また、autocomplere="off"とすることで、少々煩わしいオートコンプリート機能を無効にすることができます。
<input autocomplere="off" id="name" placeholder="What's your name?" type="text">
これはプライバシー保護のために良いことです。
また、もう1つできることがあります。
オートフォーカスを追加してみましょう。
<input autocomplere="off" autofocus id="name" placeholder="What's your name?" type="text">
今まではページをリロードするたびにボックスをクリックしなければなりませんでした。
でも今はページをリロードすると、カーソルがすでにそこで点滅しているので、ユーザーの手間を省くことができます。
このように、ユーザーが望む場所にカーソルを置くことで、アクセシビリティとユーザビリティを確保することができます。
さて、scriptタグの関数greetを使ってJavaScriptを導入し、onsubmit属性を使ってその関数を呼び出し、return falseで関数を呼び出してフォームをサーバに送信しないようにすることで、フォームの送信をショートカットしましたが、ここまでの内容について、何か質問はありますか?

分かりました。ややこしくなるかもしれませんが、もっと複雑にしてみましょう。
しかし、今後2週間、もっとたくさんの例を見て、サードパーティーのライブラリを使い、いくつかの構成要素を見ているうちに、よくわかるようになると思います。
これらの例に基づいて、今週、今夜、皆さんがコードを書くことを期待しているわけではありませんが、私たちはJavaScriptが一般的にどのように書かれているかのメンタルモデルを提供しているのです。
JavaScriptはCSSと同様に、少しお粗末に設計されています。
言語が混ざり始めると、他の人と共同作業するのが難しくなります。
ある言語を他の言語から独立して維持するのが難しくなります。
ですから、これらを別々にしておくことは良い事だと考えられています。
しかし、必ずしもそうとは限りません。
特にモバイルアプリの開発では、これらを元に戻そうとする傾向があります。
しかし、少なくとも開発を始めたばかりの頃は、分けた方がスッキリします。
それでは早速、ここでのコードを削除してみましょう。
(scriptタグを丸々削除する)
そして、このonsubmitハンドラを削除します。
<form onsubmit="greet(); return false;">

<form>
そして、先に進んで、ここにscriptタグを与えてみます。
(<head>の下に<script>)
同じことを少し違う方法でやってみます。
document.querySelector、今回は、formを選択します。
<script>
document.querySelector('form')
</script>
わざわざ名前を付ける必要はありません。
formは1つしかありませんから、単にformを選択すれば、私のformが出来上がります。
そして、addEventListener()というオシャレな関数を使ってみましょう。
document.querySelector('form').addEventListener()
ウェブプログラミングの世界には、イベントと呼ばれるものがたくさんあります。
ページをクリックすると、それはイベントです。
ページをドラッグしても、それはイベントになります。
携帯電話では、ページをタッチすると、それがイベントになります。
JavaScriptを使えば、プログラマである皆さんは、これらのイベントを監視(listen)し、イベントに反応して何かを行うコードを書くことができるのです。
そこで、formにEventListenerを追加して、Submitイベントを受信するようにしてみましょう。
document.querySelector('form').addEventListener('submit')
formが送信されたら、コードは何をすればいいでしょうか?
greet関数を呼び出したいとします。
document.querySelector('form').addEventListener('submit', greet);
さて、greet関数を動作させるためには、再度これを導入する必要があります。
では、早速greet関数を作ってみましょう。
function greet()
{
let name = document.querySelector('#name').value;
alert('hello,' + name);
}
これでgreetができました。
この行は次のことをします。
document.querySelector('form').addEventListener('submit', greet);
「ブラウザよ、formを見つけてくれ。そして、submitイベントを受信するイベントリスナーを追加して、そのイベントが起こったら、この関数を呼んでくれ」と言っています。
これは、先週のラムダの例と非常に似ています。
つまり、sorted関数に関数を渡して、キーではなく値でソートするように指示したのと少し似ています。
ソートするための関数を定義した時の構文を思い出してください。
私自身がgreetを呼び出したいわけではないことに注意してください。
私自身が13行目でgreetを呼び出したいわけではありません。
準備ができたらgreetを呼び出すようにブラウザに伝えたいのです。
(※greetになっているのに注意。greet()だと、そこをコンピュータが読んだ時点でgreetを呼び出してしまう。)
ですから、関数を名前で渡しています。
それでは、保存してリロードしてみましょう。
見た目は変わりませんが、ボックスにDavidと入力してGreet meを押すと…
(何も起こらない)
あれ?何も起こりませんでした…
何か問題が発生したら、開発者ツールに戻ってみましょう。
そして、ネットワークではなくコンソールを見てみましょう。
ここでは、皆さんの新しい友人が、皆さんがJavaScriptのコードで犯したすべての間違いを表示してくれるでしょう。
pythonやC言語のように、ターミナルウィンドウにエラーが表示されます。
JavaScriptはクライアント側、つまりユーザーのブラウザの中で実行されているので、ターミナルウィンドウを見るだけではダメなのです。
テストの際は自分のブラウザで見るしかありません。
案の定、script2.html:15 Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')とあります。
これは微妙なところですが、よくあることなのでわざとやってみました。決して間違えたわけではありません。
IDEに戻ってみます。
ブラウザはとてもナイーブなものです。
派手で強力になっているように見えても、pythonやCがそうであったように、上から下へと、左から右へと、私たちの言うことを文字通りに受け取ります。
13行目でformタグの問合せをしていますが、21行目までformタグが存在しないので、うまくいきません。
表示されているエラーメッセージはそれを指摘しています。
Cannot read properties of null (reading 'addEventListener')
nullはどこから来るのでしょうか?
formは13行目の時点ではnullです。
21行目まで存在していません。
では、どうやってこれを修正するのでしょうか?
1つの方法は、手っ取り早く、汚い方法ですが、これを下に移動させて、今のbodyの中、formタグの下に移動させます。
(scriptタグを丸ごとformタグの下に移動)
これでうまくいくと思います。
ブラウザに戻ってリロードしてみましょう。
エラーは消えましたが、まだ何もしていません。
Davidと入力してGreet meを押すと→hello,David
OK。正常な動作に戻りました。
しかし、pythonやC言語の場合と同様に、これは滑りやすい斜面のようなものです。
私たちの問題を解決するには、ただ単に「下に移動させれば良い」というわけにはいかないのです。
もっと良い方法があるはずです。
精神的にはプロトタイプに似ていますが、同じ方法ではありません。
JavaScriptでは、この問題を次のように処理しています。
これを元に戻して、現在のscriptがある場所に戻ると、代わりに次のようなことができます。
document.addEventListener('DOMContentLoaded',listen);
document.querySelector('form').addEventListener('submit', greet);
そして、ここで2つ目の関数、listenを作ってみましょう。
そして、listen関数の中に、このコードを入れてしまいます。
function listen()
{
document.querySelector('form').addEventListener('submit', greet);
}

        document.addEventListener('DOMContentLoaded',listen);

これで2つの関数ができました。
1つは挨拶を処理するもので、そこには何の変更もありません。
そして、listenという新しい関数は、EventListenerを追加することだけが目的です。
これで終わりです。
しかし、ここで18行目に注目してください。
document.addEventListener('DOMContentLoaded',listen);
document自体にEventListenerを追加して、DOMコンテンツが読み込まれたとき、つまり、このツリー全体が読み込まれたとき、つまりformタグが読み込まれたとき、その他すべてのものが読み込まれたときに、先に進んでlisten関数を呼び出します。
listen関数は、投稿を受信するLintenerをformタグに追加するだけです。
これを保存してリロードします。
Davidと入力すると→hello,David
やはり正常に動作しました。
しかし、コードを下に移動して問題を解決するというような馬鹿げた手段を取る必要はありませんでした。
私はブラウザに「DOMのコンテンツが読み込まれるまで次のことをしないでください」と言っているだけです。

いいでしょう。
何か質問はありますか?
これは絶対に、今日やった構文と論理の中で最も洗練されたものだと思います。
しかし、繰り返しになりますが、私たちは今後数週間でこれを理解するための種をまいているに過ぎません。
質問はありませんか?

では、先にpythonと似ているJavaScriptのもう1つの機能を紹介して、皆さんの度肝を抜きましょう。
思い出してください。関数をある場所で定義して、その場所だけで使う、というのは、一般的にあまり格好の良いものではないですよね。
なぜ、わざわざ一度しか呼び出さない関数を書くためにコードを追加するのでしょうか?
二週間前のpythonを思い出してください。
関数fを定義した後、「いやいや、これは馬鹿げている。ラムダ関数、匿名関数を使おう、基本的には一箇所でしか使われないから」と言いました。
だから、次にやることは最も醜いものになるでしょうが、これで良いのです。
DOMのコンテンツが読み込まれた時にlistenという関数を呼び出したい、ということがわかっていれば、その関数に名前を付ける必要はありません。
document.addEventListener('DOMContentLoaded',listen);
実際に、その関数をここに置くことができます。
文字通り、ここ(listenの位置)にコピーペーストします。
document.addEventListener('DOMContentLoaded',
function listen()
{
document.querySelector('form').addEventListener('submit', greet);
}
)
他の人がやっていることと一貫性を持たせるために、少しスタイルを変えてやってみましょう。
document.addEventListener('DOMContentLoaded',function listen(){document.querySelector('form').addEventListener('submit', greet);});
ここで注目して欲しいのは、このようにしたことです。
文字通り、addEventListenerの第2引数としてその関数を移動させました。この時点でその名前は必要ありません。
私はただこれを行うつもりです。
(↓listenという関数の名前を削除する)
document.addEventListener('DOMContentLoaded',function(){document.querySelector('form').addEventListener('submit', greet);});
JavaScriptでラムダ関数に相当するものは、文字通り名前のない関数と言います。関数は()括弧を伴います。
ここで言っているのは、グローバル変数であるdocumentオブジェクトに、DOMコンテンツが読み込まれたことを検知するEventListenerを追加せよ、ということです。
document.addEventListener('DOMContentLoaded',
さて、DOMコンテンツが読み込まれたらどうしたいのでしょうか?
ラムダ関数として知られているこの無名関数を呼び出します。
function()
しかし、私たちが何をしようとしているかに注目してください。
formを問合せ、submitの際にgreet関数を呼び出すためのEventListenerを追加しています。
{document.querySelector('form').addEventListener('submit', greet);
しかし、その必要はありません。
greet関数も名前を付ける必要はありません。
その関数を宣言している部分を削除し、もう1つ無名関数を作ってみましょう。
greet関数部分をここ(greetの名前がある位置)にコピーペーストしましょう。
document.addEventListener('DOMContentLoaded',function(){
document.querySelector('form').addEventListener('submit',function(){
let name = document.querySelector('#name').value;
alert('hello,' + name);});});
ふう。確かに恐ろしげだし、少なくとも暗号のようだし、この手のものが好きかどうかにもよりますが、楽しいかもしれませんね。
でも、基本的な構成要素に過ぎません。
pythonでは、名前を持たない関数を定義することができます。
これは素晴らしいことです。ある関数を別の関数に渡したい場合、文字通り、サポートされている構文を使ってコードを書く事ができるからです。
JavaScriptではラムダという言葉は使いませんが、名前のない関数という言葉を使います。()括弧も使います。
そして、{}中括弧の中にコードを書き出すことができます。
ここでもう1つ括弧を付けているのは、すでにaddEventListenerという関数の中にいるからです。
繰り返しになりますが、これには抵抗があるかもしれません。確かにこの段階では問題はありません。
しかし、私たちは今、これらの異なるアイデアを上に上に重ねているだけです。
それでは、これらのイベントを使って何ができるのか、あらかじめ用意された例をお見せしましょう。
ブラウザで検知することのできるイベントを網羅しているわけではありませんが、このリストには送信だけでなく、クリックやドラッグ、キーの押下、マウスの移動、マウスの下への移動、ボタンの上下、タッチや移動などのイベントがあります。
blur
change
click
drag
focus
keyup
load
mousedown
mouseover
mouseup
submit
touchmove
unload
このように、実際に検知できるイベントのリストがあります。
IDEに戻って、あらかじめ用意されたhello5.htmlというサンプルを開いてみましょう。
hello.htmlにはこのイベントの実例があり、いくつかのことを行っています。
DOMContentLoadedを受信していますが、次にKeyupを受信しています。
keyupで何をしようとしているのでしょうか?
さて、見てみましょう。
ブラウザに移動します。
hello5.htmlというファイルを開きます。
(入力ボックスが表示される)
ここで注目して欲しいのは、Davidと入力してみると…
(ボックスの下にリアルタイムでhello,Davidと表示される)
ウェブページ自体が私と対話していることに注目してください。
私が名前を削除するとすぐにhello,whoever you areと言います。
JavaScriptを使えば、単にアラートを出すだけでなく、ウェブページのコンテンツを変更することさえできるのです。
詳細は説明しませんが、ここにあるようなコードを使えば、ページそのものを変更することができます。
ここで気づいたのですが、これはちょっと見苦しい構文ですね。
連結する必要もありません。
pythonのf文字列のように、JavaScriptではバッククオートとドル記号、そして馬鹿げた{}中括弧を使って同じことができます。
`hello,${input.value}`
これは私の偏見ですが。
馬鹿げた構文だと思いますが、pythonの時と全く同じアイデアです。
繰り返しになりますが、初期段階ではこういったことでどうしてもつまづいてしまうものですが、言語に慣れてくると、アイデアに集中することができるようになります。

いいでしょう。
それでは、JavaScriptの機能を理解してもらうために、他にもいくつか用意された例を見てみましょう。
これはbackground.htmlというプログラムです。
このウェブページには3つのボタンが表示されます。
ウェブページにボタンを実装するには、様々な方法があります。
文字通りbuttonタグを使うことができます。
ここにはquerySelectorを使ったコードがたくさんありますが、もっと強力なことができます。
JavaScriptでdocument.querySelector('body')と言ってbodyを選択すると、ページのbodyの中にある特別な変数、つまりstyleというタグにアクセスできるのです。
そして、コードを使ってCSSプロパティのスタイルを変更することができます。
残念ながらこの仕様はちぐはぐです。
CSSでは、先ほど見たようにbackground-colorとなります。
残念ながら、プログラミング言語であるJavaScriptではん、これは算術として解釈されるので、背景マイナス色の意味になります。
そこで、ハイフンを含むCSSプロパティは、両者を区別するために、代わりにbackgroundColorのようにする、と決めました。
しかし、考え方は全く同じです。
このbackground.htmlというファイルを開くと、R、G、Bという3つのボタンがある非常にシンプルなページがあります。
これらのボタンをクリックすると、あらかじめクリック用のEventListenerを定義していることに気づきます。
そして、クリック音が鳴るたびに、ページのCSSを変更しています。
(Rをクリックすると赤に、Gをクリックすると緑に、Bをクリックすると青に背景色が変わる)
更に、開発者ツールを開いてみましょう。
今日最後のタブは「Elements」です。
どんなに醜いHTMLでも、開発者ツールのElementsタブを使えば、とてもきれいに印刷され、カラフルに表示されます。
また、リアルタイムに変化する実際のCSSも表示されます。
では、このページをリロードしてみましょう。
デフォルトではページの背景は白になっています。
そしてここでは、確かにbodyにはstyle属性が付いていません。
しかし、少し拡大してRをクリックすると、ページ下部のHTMLを見ることができます。
(Rをクリックすると、bodyのstyle属性に背景色を赤にするコードが追加される)
chromeは背景色の赤をダイナミックに追加しました。
緑や青も同様です。
このように、開発者ツールを使えば、自分のウェブサイトを操作してDOMで何が変化しているかを確認することができます。
このツリーの属性をリアルタイムに変更しているので、ページがよりダイナミックになっているのです。
これは強力です。
例えば、harvard.eduに行って、開発者ツールを開いてみましょう。
ここでは、Elementsタブでharvard.eduのすべてのHTMLを見ることができます。
ここにはたくさんのHTMLがありますが、これらの三角形が折りたたんでいます。
特定のものを見たい場合は、次のようにしてみましょう。
変えたら面白そうなものはあるでしょうか?
これにしましょう。
書き換えたいものがあるので、About Harvardを右クリックしてInspect(検証)をクリックしてみましょう。
すると自動的にElementsタブにAbout Harvardを作った時のHTMLが表示されます。
ここには他のタグもあります。
spanは別のものです。
小段落のようなもので、すべて1行になっています。
どこかで見たようなクラスですね。
lg-nav-txtは、ハーバード大学がクラス名として考案した大きなナビゲーションテキストでしょうか。
ここで何ができるかというと、Yaleに変更してEnterを押すと…ほら、Harvard.eduをハックしました。
(コードを書き換えると、About HarvardをAbout Yaleに変更できた)
ここで何が起こっているのかを理解することは重要です。
ここにダウンロードされたHarvard.eduのローカルコピーを変更しているだけです。
Harvard.eduにアクセスしても、そのページを変更したわけではないので、それ自体はハッキングではありません。
しかし、これは本当に、ウェブページのデザインを学ぶ方法でもあります。
Yale.eduに行って、同じようにYaleのすべてのHTMLを見て、ここを変更することができます。
About Yaleを右クリックしてみましょう。
Inspect(検証)をクリックします。
これをHarvardに変更してみましょう。
悪意のあることもできますが、それは自分のマシンの中だけです。
右側の開発者ツールを見ると、現在そのタグに適用されているCSSスタイルがすべて表示されています。
これを見てください。
右下の色をff0000に変更して、Enterを押してみましょう。
ほら。
この行にあるYaleのすべてのタグが赤に変わりました。
実際のサーバ上で内容を変更しているわけではないので、ハッキングではありませんが、ブラウザを使って自分のページの美観を微調整したり、色々いじったり、新しいプロパティを試したりするのはとても簡単です。保存する準備ができたら、それをテキストエディタに書き出すこともできます。
他にどんなことができるでしょうか?
では、最後にいくつかの例を紹介しましょう。
size.htmlを見てみましょう。
ここでは、最初のフォントサイズでラテン語のテキストを表示していますが、ウェブフォームでよく見かける小さなドロップダウンメニューを使用しています。
(文章の下にドロップダウンメニューがある)
initial large small…
このテキストを大きくしてみましょう。
(largeにすると、文字が大きくなる)
もっともっと大きくしてみましょう。
(extra-largeにするともっと文字が大きくなる)
これはJavaScriptを使って、このドロップダウンメニューのchangeイベントを受信し、それに対応して特定の段落のテキストのサイズを変更しているだけです。
別なことをしてみましょう。
昔、私がHTMLを学んだ頃、HTML1.0(今は5までありますが)にはblinkというHTMLタグがあり、これは文字通りこれを行うものでした。
(helloというメッセージが点滅している)
私が最初に作ったホームページでは、恐らく「私のホームページにようこそ!」というメッセージがひどく醜く点滅して訪問者を迎えたことでしょう。
しかし、JavaScriptを使えば、同じことができます。
ここで開発者ツールのInspect(検証)を開いてみましょう。
blink.htmlというファイルにJavaScriptのコードを書いていて、半秒か1秒ごとにbodyのスタイルを表示/非表示の間で切り替えています。
(コード自体がvisibleとhiddenを行ったり来たりしている)
ちょっとしたお楽しみとして、blink.htmlのHTMLを実際に見てみると、JavaScriptにはwindow.setintervalというクールな関数があり、ミリ秒単位で関数を呼び出すことができます。
この関数を更に高速に変更して、100ミリ秒ごとに実行し、保存してリロードすると、さらに高速に点滅しているのがわかります。
このような間隔をコードに登録しておけば、何度でも繰り返し実行することができるわけです。
更に素晴らしいこともできます。別のURLを取得してみましょう。
これはgeolocation.htmlというファイルです。
このファイルでは、あなたが世界のどこにいるのかを把握しようとするコードを事前に記述しています。
プライバシーの観点から、私たちは皆さんがどこにいるのかを勝手に把握することはできません。
代わりに、次のようなプロンプトを表示します。ブラウザが代わりに行います。
先に進み、このクエリを許可します。
そうすると、このファイル、geolocation.htmlは、あなたのGPS座標を表示します。
特に面白いものではありませんが、Googleマップなどにアクセスすると、文字通りGPS座標を検索することができます。
私が今どこにいるのかを知りたい方は、(知らないおっさんが映る)これは私ではありません。衛生モードにして拡大すると、確かに、アメリカマサチューセッツ州ケンブリッジのブラットル・ストリートにあるアメリカン・レパートリー・シアターの一部にいます。
JavaScriptを使えば、ユーザーがどこにいるのかまで把握できるというのは、かなり気味が悪いですね。
一見すると不気味ですが、Uber EatsやGrubhub、あるいは天気予報などのウェブサイトで、位置情報を求められることがあります。これはどうやっているのでしょうか?
これらのウェブサイトのプログラマは、今geolocation.htmlで行ったように、navigator.geolocation.getCurrentPositionのようなコードを記述しています。
許可を得た上でユーザーの位置情報を伝えるのは、ブラウザに組み込まれた機能なのです。
最後に、JavaScriptの例を紹介しましょう。
オートコンプリートは、もっと素敵な方法で実装できます。
今日の講義の前に、Pset5のスペルチェッカで使った14万語以上の単語からなるlargeというテキストファイルを、対応するlarge.jsというJavaScriptファイルに変換し、ここでオートコンプリート機能が使えるようにしておきました。
Aを入力すると、Aで始まるすべての単語が表示されます。APと入力すると、APで始まるすべての単語に変わります。
これがオートコンプリートの仕組みです。
JavaScriptを使って、何を受信しているのでしょうか?
先ほどのイベントのリストに戻ると、きっとkeypressやkeyupのイベントを受信しているはずです。
ユーザーがキーを押すのを受信し、ユーザーが文字を入力するとすぐに、恐らく.value構文を使って人間が入力した値を取得し、それをページに表示するでしょう。そして、動的にli要素をページに追加したり削除したりしているのでしょう。
繰り返しになりますが、この方法は実際に見たわけではありませんが、構成要素はすでに存在します。
あなたはもうウェブページのスタイルを変更することができます。
ページにHTMLを追加することもできます。
そして、これらの種類のイベントを受信することもできます。
さて、このようにURLを利用できるのはJavaScriptだけではありません。

最後にもう1つ、pythonを使ったデモを行ってみましょう。
今回はpythonを使ってこのジャック・オー・ランタンでちょっとしたことをします。
(ジャック・オー・ランタンの照明を持ってくる)
ジャック・オー・ランタンを私の方に近づけてみましょう。
ランタンの中に電球が入っているのがわかると思います。
ランタンを前に向けてみましょう。
このジャック・オー・ランタンの中の電球は、実はインターネットに接続された最新のLED電球です。
これはインターネットに接続されたIoT(Internet of Things)デバイスです。
この電球は、私が演台の上に置いているこの小さなワイヤレスデバイスと繋がっています。このデバイスはハーバード大学のネットワークに接続されています。
そして、私のラップトップもハーバードのネットワークに接続されています。つまり、私のMacや皆さんのPCでコードを書いて、ローカルインターネット、ローカルネットワークを使って、この電球に話しかけることができるのです。
このような機器にはAPI(アプリケーション・プログラミング・インターフェース)が用意されていることが多いのですが、それは簡単に言うとURLに基づいています。
単純なURLなので、あるHTTPリクエストを電球に送ると、電球は自分で電源を切ったり、入れたり、何かをしたりします。
また、別のリクエストをすると、それに応じた動作をしてくれます。
すべてのAPIがそうであるわけではありません。しかし、ウェブプログラミングに移行したからといって、pythonを置き去りにするわけではありません。
実際、来週はpythonを全面的に復活させ、SQLを使って、HTML、CSS、JavaScript、python、SQLの5つの技術を組み合わせ、本格的なウェブアプリケーションに結びつけていきます。
そのために、ここではpythonでlight.pyというプログラムを作ります。
クラウドではないので、自分のMacで作っています。
ハーバード大学のローカル・ネットワーク上で行います。
2つのライブラリ、osとrequestsをインポートしましょう。
import os
import requests
これまで見たことはありませんが、pythonにはrequestsというライブラリがあり、pythonでブラウザのようにHTTPリクエストを実行することができます。
先に進み、USERNAMEという変数を宣言しましょう。
これは、USERNAMEという環境変数を取得した結果です。
プライバシー上の理由で、ハーバード大学のネットワークのためのユーザー名とパスワードをこのプログラムに入力したくなかったので、ここでは環境変数を使用しました。MacやPC、Linuxのコンピュータには環境変数と呼ばれるものが存在し、他の場所で秘密の値を保存することができます。
そして、pythonのos.getenv関数を使って、それらをコンピュータのメモリに秘密裏にロードすることができます。
USERNAME = os.getenv("USERNAME")
先に進み、os.getenv("IP")を実行して、電球のIPアドレスを取得してみましょう。
IP = os.getenv("IP")
そして最後に、URLを作成してみましょう。
http://、電球のIPアドレス、/api/USERNAME/light/1/stateとなります。
URL = f"http://{IP}/api/{USERNAME}/lights/1/state"
これは奇妙な見た目のURLですが、基本的には、http://電球のIPアドレス、私のユーザー名、光、1、状態、を表しています。
これらの値がわかれば、文字通りブラウザにコピーペーストすることができますが、代わりにプログラムでこれを行うことにします。
先に進んでリクエストを書いてみましょう。getリクエストを送りたければgetと言うこともできますが、それは私が望むものではありません。
私は電球の値を取得したいのではなく、電球の値を投稿したいのでもありません。
これまでに見たことはありませんが、APIでよく使われる第3のHTTPのための動詞putがあります。
技術的にはすべて大文字のPUTですが、コードでは小文字でputと書かれています。
これで私のMacからこの電球にメッセージを送ることができます。
それでは、このURLに次のようなpythonの辞書を入れてみましょう。
pythonのブール値であるfalseを引用符で囲まれたonというキーに入れてみましょう。
requests.put(URL, json={"on": False})
さて、jsonとはなんでしょうか?
jsonとはJavaScript Object Notationの略で、インターネット上でテキストメッセージを送るための一般的な方法です。
近いうちに目にすることになるでしょう。
しかし今のところ、これは電球にonというキーとfalseという値を持つ辞書を送っているだけです。
もし間違ったことをしていなければ、このファイルを閉じ、pythonのlight.pyを実行してみましょう。うまくいくでしょうか?
▼light.py
import os
import requests

USERNAME = os.getenv("USERNAME")
IP = os.getenv("IP")
URL = f"http://{IP}/api/{USERNAME}/lights/1/state"

requests.put(URL, json={"on": False})

(コードを実行するとジャック・オー・ランタンの照明が消えた)
ほら。
さて、この電球は私からどんなに離れていてもいいのです。
私がインターネットに接続し、インターネット上のIPアドレスにアクセスできる限り、インターネット上の文字通り別の場所にあっても構いませんが、何百人もの人が私のために電球を付けたり消したりしないように、今日はそうしませんでした。
しかし、このコードを少し変えてみましょう。
先に進み、電源を入れてみましょう。
もちろん、ご想像の通り、onをTrueに変更します。
ほとんど同じコードです。

import os
import requests

USERNAME = os.getenv("USERNAME")
IP = os.getenv("IP")
URL = f"http://{IP}/api/{USERNAME}/lights/1/state"

requests.put(URL, json={"on": True})

それではもう一度、python light.pyを実行してみましょう。
(ジャック・オー・ランタンの照明が付く)
素晴らしい。
もう少しファンシーにしてみましょう。
ここではもう少し論理的に、これまでよりも少し面白いことをやってみましょう。
そして、この点滅にも命を吹き込めないか見てみましょう。
ここで、今度は無限に何かをしてみましょう。
While Trueというのはどうでしょう。
import os
import requests

USERNAME = os.getenv("USERNAME")
IP = os.getenv("IP")
URL = f"http://{IP}/api/{USERNAME}/lights/1/state"

While True:
requests.put(URL, json={"on": True})
つまり、永遠にこのデモは続く、ということです。
単にオン/オフを繰り返すのではなく、明るさを254の値に変更してみましょう。
While True:
requests.put(URL, json={"bri":254, "on": True})
次に、time.sleepを1秒実行します。
time.sleep(1)
そして、1秒後に同じURLに別のリクエストを送り、onがFalseになったpython辞書を送信します。
そして、1秒間スリープさせます。
While True:
requests.put(URL, json={"bri":254, "on": True})
time.sleep(1)
requests.put(URL, json={"on": False})
time.sleep(1)
気づいたかもしれませんが、別のライブラリが必要です。
timeをインポートする必要があります。
import time
すごいことのように聞こえますが、これは単にtimeというライブラリです。
ファイルを保存したので、永遠にオンのリクエストとオフのリクエストを送ることになります。
そして、いよいよ最後の仕上げ、python light.pyです。
(ジャック・オー・ランタンが点滅を始める)
よーし!フゥー!
OK。
今日のCS50はこれでおしまいです。
次回にお会いしましょう。

この記事が気に入ったらサポートをしてみませんか?