質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CGI

CGI(Common Gateway Interface)とは、Webサーバー上でユーザプログラム動作させる仕組みのこと。また、動かす前提のプログラムをCGIと呼ぶこともあります。HTMLなどの静的な情報に限らず、プログラムの処理結果をベースにした動的情報の提供が可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

3671閲覧

cgiは動作するのに値がブラウザで確認できない。

meron-pan

総合スコア44

CGI

CGI(Common Gateway Interface)とは、Webサーバー上でユーザプログラム動作させる仕組みのこと。また、動かす前提のプログラムをCGIと呼ぶこともあります。HTMLなどの静的な情報に限らず、プログラムの処理結果をベースにした動的情報の提供が可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/10/12 11:55

編集2018/10/13 15:30

前提・実現したいこと

pythonの標準ライブラリhttp.serverを使ってローカルでサーバーを作り、データの通信実験をしてみました。
しかし、cgiは「CGI script exited OK」と出るのに、POST通信ではブラウザには何も返って来ていないことになっていて困惑しています。
これはコードのミスでした(javascriptで受け取るコードを実行していなかった)のですが、結局受信した結果で例外が発生し、その例外の内容もundefinedになってしまい原因がわかりません。
サーバーに対する知識は全くないので、ネットのありとあらゆる場所からコードを引っ張って作ったコードですが、問題点を教えてください。

発生している問題・エラーメッセージ

cgiは動作するのに値がブラウザで確認できない。(確認として、POST通信ではない状態で、アクセスしたらhtmlを返すコードを追加しましたところ、「Content-Type:」だけが表示されました。※単純なhtmlのミスでした。スイマセン。修正しました)

該当のソースコード

cgi

python

1#!/usr/bin/python3 2# -*- coding: utf-8 -*- 3 4import io 5import os 6import sys 7import cgi 8import cgitb 9import urllib.request 10import json 11 12cgitb.enable() 13 14sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8') 15sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') 16sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') 17 18 19html = ''' 20<!DOCTYPE html> 21<html lang="ja"> 22<head> 23<meta charset="utf-8"> 24<style> 25body { background-color: cyan; } 26</style> 27<title>初めてのpython3CGI</title> 28<meta name="description" content=""> 29<meta name="keywords" content=""> 30</head> 31<body> 32<header> 33<h1 id="titlename">初めてのpython3CGI</h1> 34</header> 35<div id="contents"> 36<article> 37<section id="top" style="display:block"> 38</section> 39</article> 40</div> 41<footer> 42</footer> 43</body> 44</html> 45''' 46 47print("Access-Control-Allow-Methods: GET ,POST ,OPTIONS") 48print("Access-Control-Allow-Origin: *") 49print("Access-Control-Allow-Headers: *") 50 51if os.environ['REQUEST_METHOD'] == 'POST': 52 form = cgi.FieldStorage() 53 result_json = {'key': 'value'} 54 print("Content-Type: application/json; charset=utf-8\r\n") 55 print('\n') 56 print(json.dumps(result_json)) 57else: 58 print("Content-Type: text/html; charset=utf-8\r\n") 59 print('\n') 60 print(html) 61 62

html

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>Javascript試験用</title> 7 <script charset="UTF-8" type="text/javascript" src="ajax.js"></script> 8</head> 9 10<body> 11 <div id="outputArea"></div> 12 <div id="inputArea"> 13 <form> 14 <textarea name="input" rows="2" cols="20"></textarea> 15 </form> 16 <button id="ajaxButton" type="button">決定</button> 17 </div> 18 <div id="dispArea"></div> 19</body> 20 21</html>

javascript

1 2ajaxSend = function (json) { 3 console.log("a") 4 var xhr = new XMLHttpRequest(); 5 xhr.open("POST", 'http://localhost:8000/cgi-bin/server.py', true); 6 xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); 7 xhr.send(json); 8  ajaxGet(); 9} 10 11ajaxGet = function () { 12 var req = new XMLHttpRequest(); 13 try{ 14 if (httpRequest.readyState === XMLHttpRequest.DONE) { 15 if (httpRequest.status === 200) { 16 console.log(req.responseText) 17 alert(req.responseText); 18 }else { 19 alert('リクエストに問題が発生しました'); 20 } 21 } 22 } 23 catch(e){ 24 alert('例外を補足:'+e.description); 25 } 26} 27 28json = { 29 "messages": 30 [ 31 { 32 "date": "2012/1/12 19:12", 33 "text": "こんばんは" 34 } 35 , 36 { 37 "date": "2012/1/11 19:12", 38 "text": "Hello" 39 } 40 ] 41} 42 43window.onload = function(){ 44 document.getElementById("ajaxButton").addEventListener('click',function(){ajaxSend(json)}) 45}

補足情報(FW/ツールのバージョンなど)

使用しているpythonはpython3.7、ブラウザはfirefox、実行環境はwondows10homeです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wwbQzhMkhhgEmhU

2018/10/13 02:32

サーバーに対する知識は全くないのに、ネットのありとあらゆる場所からコードを引っ張って作ったコードを動かそうとしてるところが問題です。習得にかかる絶対的な時間には個人差がありますが、そのやり方よりは、Hello, World.から順に少しずつできることを増やしていった方が、常人ならよほど早いと思います。例外的にあなたのような方法であっという間に学習される方もいますが、そういう方はそもそも他人に質問するより自分で調べて、瞬間的に解決してしまい、こんなところにいることはありません。
meron-pan

2018/10/13 06:12

回答する気が全くないのに、修正依頼で他人を否定することしかできないのであれば、そもそもこんな質問に回答しないでいただきたいですね。知識が欲しいからここで質問しているのですよ。それを「まず先にHello,Worldからできますか?」と聞かれてしまってはこちらも質問していて悲しくなります。
meron-pan

2018/10/13 06:14

もし質問内容に不備があるのであれば、修正します
guest

回答1

0

自己解決

とりあえずですが自己解決しました(超初心者の解決ですが・・・)。フレームワークは一切なしです。
どうやら、pythonのCGIでは、JavaScriptサイドで

JavaScript

1xhr.setRequestHeader('Content-Type', 'application/json');

の記述には対応してくれない模様です。

JavaScript

1 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

は反応するっぽいので、これだとjson形式で送信すると値が返ってきませんが、"foo=bar&lorem=ipsum"の形のデータはjavascriptで受け取ることが出来ました(色々と要らない値もセットで来るけど...)。

Javascript

1//どちらか一つにする 2var xhr = new XMLHttpRequest(); 3var req = new XMLHttpRequest(); 4

は送信と受信でセットのようなので、送信と受信で別々に定義したら動かなくなります。

Javascript

1try{ 2 if (httpRequest.readyState === XMLHttpRequest.DONE) { 3 if (httpRequest.status === 200) { 4 console.log(req.responseText) 5 alert(req.responseText); 6 }else { 7 alert('リクエストに問題が発生しました'); 8 } 9 } 10 } 11 catch(e){ 12 alert('例外を補足:'+e.description); 13 } 14

これは、通信が上手く動作しているかを確認するコードですが、send()した後にすぐにやったら、うまくいかないのは当たり前でした(元のコードをしっかり見ていなかったのが原因でした。xhr.onreadystatechangeのところに貼れば問題ないはず)

下の方に改良をおこなったpythonとjavascriptを貼っておきます。

JavaScript

1var xhr = new XMLHttpRequest();//受信と送信で同じものを使わなければならない(要は送信と受信でセット) 2 3ajaxSend = function () { 4 5 xhr.open('POST', 'http://localhost:8000/cgi-bin/server.py', true); 6 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 7 xhr.send("foo=bar&lorem=ipsum");//データはこの形式にしないとCGIで認識してくれない 8 ajaxGet() 9 10} 11 12ajaxGet = function () { 13 xhr.onreadystatechange = function(){//通信の状態が変化するごとに発火する関数 14 console.log(xhr.readyState)//通信状態の確認 15 console.log(xhr.responseText)//返ってくる内容(通信の状態が3か4で返ってくる) 16 } 17} 18 19window.onload = function(){ 20 document.getElementById("ajaxButton").addEventListener('click',ajaxSend) 21}

python

1#!/usr/bin/python3 2# -*- coding: utf-8 -*- 3 4import io 5import os 6import sys 7import cgi 8import cgitb 9import urllib.request 10import json 11#エラーをhtml形式でファイルとして吐かせるためのコード 12cgitb.enable(display=0, logdir="cgi-bin/tmp") 13#文字のエンコード指定 14sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8') 15sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') 16sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') 17 18#サーバーにアクセスできているかを確認するためのhtml 19html = ''' 20 21<!DOCTYPE html> 22<html lang="ja"> 23<head> 24<meta charset="utf-8"> 25<style> 26body { background-color: cyan; } 27</style> 28<title>初めてのpython3CGI</title> 29<meta name="description" content=""> 30<meta name="keywords" content=""> 31</head> 32<body> 33<header> 34<h1 id="titlename">初めてのpython3CGI</h1> 35</header> 36<div id="contents"> 37<article> 38<section id="top" style="display:block"> 39</section> 40</article> 41</div> 42<footer> 43</footer> 44</body> 45</html> 46''' 47#通信の許可の設定(httpリクエスト:ユーザーには見えないが設定として必要) 48print("Access-Control-Allow-Methods: GET ,POST ,OPTIONS") 49print("Access-Control-Allow-Origin: *") 50print("Access-Control-Allow-Headers: *") 51 52form = cgi.FieldStorage() 53#javascriptからのデータの確認のため、テキストファイルに内容を出力させる、デバックにも便利 54f = open("cgi-bin/log.txt","w") 55f.write(str(form))#formをテキストに変換 56 57#ポスト通信であれば、受け取った内容を、異なるならhtmlを返す 58if os.environ['REQUEST_METHOD'] == 'POST': 59 print("Content-Type: application/json") 60 print("charset=utf-8\r\n") 61 print('\n') 62 f.write("POST通信")#ポスト通信が行われたのなら、テキストファイルに出力 63 print(form) 64else: 65 print("Content-type: text/html") 66 print("charset=utf-8\r\n") 67 print('\n') 68 print(html) 69 70 71f.close()#テキストファイルを閉じる 72

参考文献
始めましょう - ウェブデベロッパーガイド | MDN

投稿2018/10/14 08:22

meron-pan

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問