ヘルニアクソ野郎エンジニアblog

~ヘルニアでHell near~

CGIでjavascriptからpythonへ値を渡す方法

calendar

reload

CGIでjavascriptからpythonへ値を渡す方法

電子工作でjsからpythonへ値を渡す必要があったので(raspberrypiに立てたWEBサーバーにHTMLを格納し、それをコントローラーとしてjsのイベントが発生すると非同期通信でpythonスクリプトを実行させてサーボモーターやらを動作させたかった)、色々調べているとCGIを使うことでこれが実現可能な事がわかりました。今回はその時のメモになります。

実際にjsからpythonへ値を渡したいケースなんてのが存在するのかよく分かりませんが、誰か1人でもお役に立てたなら幸いです。

プログラムの流れ的には、

ブラウザ(python httpserver)→javascript(Ajax)→pythonscript(cgi)

となります。

OSはwindows、linux、共にpythonをインストールしていればとりあえずどちらも実行できる事を確認しています。

ファイル構成は下図のような感じです。cgiを使うのでcgi-binディレクトリが必須で、その配下にpythonスクリプトを格納します。

ファイル構成

 

スポンサーリンク

プログラム

html/css

簡単なリモコン画面を作成しました。

続いてjavascript

 

javascript

jqueryで、htmlで作成したボタンを押すとイベントが発生するようにしています。

肝心なのがajaxを使っている所で、cgi-binディレクトリのreceive.pyにdataの内容を非同期でpostします。

続いて、postされた値を受け取るためのpythonスクリプトを作成します。

 

python

先頭の#!で始まる記述は「シバン」と呼ばれ、これがないとscriptファイルとしてpythonが動作しません。これはpythonインタプリタの格納場所を示しています。つまり、jsのajaxでpostする先のurlにシバンが記述されていれば、自動的に「ファイル名.py」が実効される仕組みです。上のものはwindowsの場合で、linuxですと#!/usr/bin/python3 とかになります。

cgi.FieldStorage() でpostされた値を受け取って、getvalue(‘name’)で、kye(name)に紐づいた値を抜き取っています。

続くif文で、postされた値を照合して、とりあえず今回はpostされた値をそのままjsに返しています。

jsに値を返却する際は、

print()

を使います。先に ’Content-type: text/html\n’ をprintしていますが、これがないとjsに値を返却出来ないみたいです。(header情報に乗せる必要がある)

 

実行方法

WEBサーバーを立ち上げる必要があります。

flask等を使えばもっと簡単に出来るようですが、今回はpythonで最もお手軽につかえる「python http.server」を使います。

シェルで今回作成したファイルを格納しているディレクトリまで移動して、そこでWEBサーバーを立ち上げます。

コマンドは以下の通り。

8000はポート番号になりますので、他で使用していれば他に変える必要があります。

サーバーが立ち上がれば、chromeブラウザからlocal.host(127.0.0.1:8000)にアクセスします。

htmlの操作ボタンをクリックして、chromeのデベロッパーツールのコンソール画面に値が返ってくればOKです。

値が返ってくる=jsからpythonに値の受け渡しが出来ている証拠になります。

一応動画を載せておきます。↓

 

ハマりどころ

①windowsでは sys.stdin.readline() でjsから文字列を直接受け取る事ができましたが、linuxではなぜか値を受け取れませんでした。前途したcgi.FieldStorage() でpostされた値を受け取って、getvalue()で、kyeに紐づいた値を抜き取れば、winでもlinuxでもOKでした。

②シェルからpython http serverの起動時、「–cgi」が必須。これが抜けるとcgi-binのディレクトリとその配下のpythonスクリプトがあっても動作しません。