#author("2022-03-03T04:24:50+00:00","","")
#author("2022-03-03T04:30:41+00:00","","")
&br;

-----
#contents
-----

&br;

* &size(20){CGIとは}; [#tf596f47]

~
&size(15){ざっくりいうと…};~
~
&size(15){''JavaScriptから「Pythonなどのプログラム」を実行できるしくみ''です.};~
~
&size(15){JavaScriptとプログラム間で,値の受け渡しもできます.};~
~
&size(15){&color(orange){''(研究室のサーバで動かすときは,ちょっと手こずるので,''};};~
&size(15){&color(orange){''注意してください.)''};};~
~

* &size(20){やりかた}; [#vf0bb5fb]

&br;

&size(15){HTMLで2つの値を入力してもらい,JavaScriptでそれらをプログラムに送り,};
&size(15){プログラム内でそれらの積を求めて,それを返す};~
&size(15){HTMLとJavaScript,Pythonの例です.};~
~
#ref(aaa.jpg,,)
~
&size(15){最低限必要なものは,&color(blue){''青太字''};で書いています.};~
~
&size(15){/index.html};~
-----
&size(15){<!DOCTYPE html>};~
&size(15){<html lang = 'ja'>};~

&size(15){<head>};~
&size(15){<meta charset = 'UTF-8'>};~
&size(15){</head>};~

&size(15){<body>};~
&size(15){<input id = "input1" type = "text">x<input id = "input2" type = "text">=};~
&size(15){<span id = "result"></span>};~
&size(15){<br>};~
&size(15){<input type = 'button' value = 'EXECUTE' onClick = 'execute()'>};~
&size(15){<script type = 'text/javascript' src = 'main.js'></script>};~
&size(15){</body>};~

&size(15){</html>};~
-----

~
&size(15){/main.js};~
-----
&size(15){async function execute() {};~

&size(15){&color(blue){''const url = "./cgi-bin/program.py";''};};~
&size(15){&color(gray){// プログラムの相対パス};};~
&size(15){&color(gray){//(プログラムは「/cgi-bin」下にいれるのが定石です)};};~

&size(15){const left = document.getElementById("input1").value;};~
&size(15){const right = document.getElementById("input2").value;};~
&size(15){&color(gray){// 入力された値を読みとります};};~

&size(15){&color(blue){''const sendData = {''};};~
&size(15){"left": left,};~
&size(15){"right": right,};~
&size(15){&color(blue){''}''};};;~
&size(15){&color(gray){// プログラムに送りたい値を,連想配列で書きます};};~

&size(15){&color(blue){''const request = {''};};~
&size(15){&color(blue){''"method": "POST",''};};~
&size(15){&color(blue){''"headers": {"Content-Type": "text/json", "charset":"utf-8"},''};};~
&size(15){&color(blue){''"body": JSON.stringify(sendData),''};};~
&size(15){&color(blue){''}''};};;~

&size(15){&color(blue){''const responce = await fetch(url, request);''};};~
&size(15){&color(gray){// ここでプログラムを実行させます};};~
&size(15){&color(gray){//「responce」には,プログラムからやってきたデータなどが入ります};};~

&size(15){&color(blue){''const receivedData = await responce.json();''};};~
&size(15){&color(gray){// プログラムからやってきたデータを,使いやすいように連想配列に変換します};};~

&size(15){const html = receivedData["result"];};~
&size(15){&color(gray){// あとはふつうの連想配列とおんなじように使えます};};~

&size(15){document.getElementById("result").innerHTML = html};~
&size(15){&color(gray){// HTMLに反映します};};~

&size(15){}};;~
-----
~
&size(15){/cgi-bin/program.py};~
-----
&size(15){&color(blue){''#!C:\Users\...\AppData\Local\Programs\Python\Python38\python.exe''};};~
&size(15){# coding: utf-8};~

&size(15){&color(gray){# 1行目で,「#!」に続けて,Pythonのインタプリタを絶対パスで指定します};};~

&size(15){&color(blue){''import sys''};};~
&size(15){&color(blue){''import io''};};~
&size(15){&color(blue){''import json''};};~

&size(15){&color(blue){''sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding = "utf-8")''};};~
&size(15){&color(blue){''sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding = "utf-8")''};};~
&size(15){&color(blue){''sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding = "utf-8")''};};~
&size(15){&color(gray){# 日本語(2バイト文字)をふくむデータを送受信するときに};};~
&size(15){&color(gray){# 文字化けしないようにするためのおまじない};};~

&size(15){&color(blue){''received_data = json.loads(sys.stdin.readline())''};};~
&size(15){&color(gray){# 「received_data」に,JavaScriptからやってきたデータが,辞書形式で入ります};};~

&size(15){f = open("./cgi-bin/log.txt", "w", encoding = "utf-8")};~
&size(15){&color(gray){# デバッグしたいときに,よく「print」文を使いたくなりますが};};~
&size(15){&color(gray){# ここでは「print」文は使えないので};};~
&size(15){&color(gray){# テキストファイルに出力します};};~

&size(15){f.write(received_data)};~
&size(15){&color(gray){# たとえば変数の中身を見たいときは,こんな感じで…};};~

&size(15){left = received_data["left"]};~
&size(15){right = received_data["right"]};~
&size(15){&color(gray){# あとはふつうの辞書形式とおなじように使えます};};~

&size(15){result = int(left) * int(right)};~

&size(15){&color(blue){''send_data = {''};};~
&size(15){"result": result};~
&size(15){&color(blue){''}''};};~
&size(15){&color(gray){# JavaScriptに送りたいデータを,辞書形式で書きます};};~

&size(15){&color(blue){''print("Content-type: text/json; charset=utf-8\r\n")''};};~
&size(15){&color(blue){''print(json.dumps(send_data))''};};~
&size(15){&color(gray){# JavaScriptにデータを送ります};};~
&size(15){&color(orange){''# HTMLを返すときは,「text/json」のところを「text/html」に''};};~
&size(15){&color(orange){''# 単にテキストを返すときは,「text/plain」にしてください''};};~
&size(15){&color(orange){''# (影響があるかどうかは分かりませんが,いちおう規則なので…)''};};~

&size(15){f.close()};~
&size(15){exit()};~
-----

&br;

* &size(20){研究室のサーバでやるときの注意点!}; [#r7c4adbb]

&br;

*** &size(20){それぞれのファイルの置くところ}; [#y38e10d8]

&br;

&size(15){''HTML,CSS,JavaScriptなど''};~
&size(15){/var/www/html/};~

&size(15){''プログラム''};~
&size(15){/var/www/cgi-bin/};~

&size(15){(プログラムを「/var/www/html/」下(「/var/www/html/.../cgi-bin/」など)においても};~
&size(15){動かないので注意!)};~

~

*** &size(20){プログラムのアクセス権限はゆるゆるに}; [#ad23ba16]

~

&size(15){どのアクセス権限が最小限必要なのかは未調査ですが,};~
&size(15){''7777''にしておくと確実です(あたりまえですが).};~

~

*** &size(20){Pythonのインタプリタ}; [#ad23ba16]

~

&size(15){''/usr/local/pyenv/versions/3.8.5/bin/python3.8''};~

~

*** &size(20){404 Not Foundが出るときは…}; [#ke55e48b]

~

&size(15){JavaScriptで指定しているプログラムのパスが};~
&size(15){間違っていないか確認してください.};~

~

*** &size(20){500 Internal Server Errorが出るときは…}; [#xd22d75c]

~
&size(15){JavaScriptで指定しているプログラムのパスは合っていますが,};~
&size(15){そのプログラムを実行している(実行しようとした)ときに,};~
&size(15){なにかしらのエラーが発生しています.};~
~
&size(15){''・プログラムの権限がゆるゆるになっているか確認してください''};~
~
&size(15){''・プログラムがちゃんと正しく実行できるか(コンパイル上のエラーがないか)確認してください''};~
&size(15){特に,インタプリタのパスが正しいか,ライブラリが(もちろんサーバ側に)};~
&size(15){インストールされているか確認してください.};~
~
&size(15){詳細なエラーログは''/etc/httpd/logs/ssl_error_log''に残されますので,};~
&size(15){それを見れば,一発で原因が分かります.};~
&size(15){…が,''それを見るためには管理者権限が必要です!''};~
&size(15){管理者権限を持てる人にお願いして,見せてもらいましょう.};~
&size(15){(管理者権限を持てるアカウントでログインして,};~
&size(15){''sudo su -''にして管理者権限になり};~
&size(15){''less +F /etc/httpd/logs/ssl_error_log''で見れます)};~
~

*** &size(20){Pythonのモジュールをインストールするときは…}; [#x37fa66e]
~
&size(15){''python -m pip install &color(gray){[モジュール名]}; -t /usr/local/pyenv/versions/3.8.5/lib/python3.8/site-packages/''};~
~
&size(15){(''python -m pip install &color(gray){[モジュール名]};''だけでやると,};~
&size(15){変なところ(自分のホームディレクトリ内)にインストールされてしまい,};~
&size(15){どれだけやってもNo module errorになります…)};~
~

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS