カテゴリー
IT programming

エックスサーバー上でPythonのCGIを使用したJSONの送受信(Ajax)を行う

前回の記事を参考に、エックスサーバー上で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}