前回の記事を参考に、エックスサーバー上でPythonのCGIに対して、JSONの送受信をテストしたいと思います。
前回の記事はこちら。
https://1-10000th.com/python-cgi-500error/
やりたいこと
PythonをCGIにして、WEBページ(Javascitpt+Ajax)からJSONを送信して、Pythonで受信して加工して、JSONを返して、WEBページで表示する。
具体的には、WEBページ(tashizan.html)から入力xと入ちょくyを、Python(response.py)にAJAXでPOST送信して、Python内で足し算して、その結果をWEBページに戻す。
WEBページのコード(tashizan.html)
bootstrap4とjQueryを使用しています。
<!doctype html> <html lang="ja"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <title>Python + Ajax</title> </head> <body> <div class="container"> <h1>PythonとAjaxで足し算するよ</h1> <form> <div class="form-group"> <label for="x">x</label> <input type="number" class="form-control" id="x" placeholder=""> </div> <div class="form-group"> <label for="y">y</label> <input type="number" class="form-control" id="y" placeholder=""> </div> <div class="form-group"> <label for="answer">answer ( x + y )</label> <input type="number" class="form-control" id="answer" placeholder="" readonly> </div> </form> </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script> $(function() { //keyup()でキーを入力するたびに発動 $('input[type="number"]').keyup(function() { //リクエスト let request = { x: $("#x").val() ? $("#x").val() : "0", y: $("#y").val() ? $("#y").val() : "0", }; console.log(request); url = "response.py" $.ajax({ type: "POST", url: url, data: JSON.stringify(request), dataType: "json", success: function(data) { $('#answer').val(data['answer']); }, error: function(XMLHttpRequest, textStatus, errorThrown) { console.log("ERROR:\n" + url + "\n" + textStatus + ":\n" + errorThrown); } }); }); }); </script> </body> </html>
Pythonのコード(response.py)
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys import json data = sys.stdin.read() params = json.loads(data) # 数字かどうかを判断する関数 def is_num(s): try: float(s) except ValueError: return False else: return True # 数字以外のものが飛んできたらとりあえず弾く if is_num(params['x']) and is_num(params['y']): result = {'answer': float(params['x']) + float(params['y'])} print("Content-type: application/json") print("\n\n") print(json.JSONEncoder().encode(result)) print('\n')
結果
https://1-10000th.com/python-cgi/tashizan.html
注意点
- 改行コードをLFにする(超重要)。
- pythonファイルは権限を705もしくは755にする。
- .htaccessにAddHandler cgi-script .pyを書く。
補足
なお、WEBページを経由せずに、SSH等でpythonプログラムの動作を確認するには、下記のようにしてpythonプログラムに、パイプでJSONを渡すことができる模様(sys.stdin.read()を使用しているので)。
JSONのキーもバリューもダブルクオテーションで囲むこと。
$ echo '{"x": "-12.5", "y": "64.3"}' | ./response.py
実行結果↓
Content-type: application/json {"answer": 51.8}