やってみた
環境はAWS EC2 Amazon linux2を使う。そこでDockerでApache2を起動する。
公式ドキュメント
https://jp.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html
を見てみたが全然わからなかった。
Dockerfile
- Apache2でWebページ公開
- run.sh でApache2起動
- sample.py の権限を緩めないとPOSTは
500 Internal Server Error
で失敗する
サーバーエラーレスポンス一覧
https://developer.mozilla.org/ja/docs/Web/HTTP/Status
FROM ubuntu:18.04
COPY ./src/index.html /var/www/html/
COPY ./src/sample.py /var/www/html
COPY ./run.sh /root/
RUN apt-get update && \
apt-get -y install apache2 && \
apt-get -y install python3 && \
chmod 755 /root/run.sh /var/www/html/sample.py
EXPOSE 80
CMD /root/run.sh
-
sed
でapache2.confを編集- CGI の実行を可能にするためExecCGIをOptionsに指定
- pythonファイルをCGIで実行するよう指定するためAddHandler cgi-scriptに.pyを指定
apache2のCGIに関しては以下リンク参照。
https://httpd.apache.org/docs/2.4/ja/howto/cgi.html
mkdir -p /var/run/apache2
mkdir -p /var/lock/apache2
. /etc/apache2/envvars
sed 's/^\tOptions Indexes FollowSymLinks/\tOptions Indexes FollowSymLinks ExecCGI/g' /etc/apache2/apache2.conf | \
sed 's/^\tOptions Indexes FollowSymLinks ExecCGI/\tOptions Indexes FollowSymLinks ExecCGI\n\tAddHandler cgi-script .cgi .py/g' > tmp.conf
cp tmp.conf /etc/apache2/apache2.conf
rm tmp.conf
a2enmod cgid
/usr/sbin/apache2 -D FOREGROUND
- Vueインスタンス内
axios.post
の第二引数にあるdataを受け取る - print関数でVueインスタンスにpythonで行った処理結果を返す
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import cgitb
cgitb.enable()
data = sys.stdin.readline()
print('Content-Type: text/html\n')
print('Hello, ' + data)
- axios を CDN から使用する
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>index</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input id="input" type="text" value="">
<input v-on:click="post" id="button" type="button" value="button">
<p id="res">{{ message }}</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: ''
},
methods: {
post: function() {
var text = document.getElementById("input").value;
axios.post('./sample.py', {
type: 'post',
data: text
}).then(function(res){
app.message = res.data;
}).catch(function(){
alert('error');
})
}
}
})
</script>
</body>
</html>
python cgiについて
https://thinkami.hatenablog.com/category/Python?page=1494886074
↑こちらの記事や
以前自分で書いた記事
https://qiita.com/quryu/items/7c4b1f2dafd1c8ca08a6
ではInternal Server Errorになってしまう。
問題個所は以下のコード。
import cgi
storage = cgi.FieldStorage()
data = storage.getvalue('data')
エラーメッセージ
File "/var/www/html/sample.py", line 9, in <module>
storage = cgi.FieldStorage()
File "/usr/lib/python3.6/cgi.py", line 566, in __init__
self.read_single()
File "/usr/lib/python3.6/cgi.py", line 757, in read_single
self.read_binary()
File "/usr/lib/python3.6/cgi.py", line 779, in read_binary
self.file.write(data)
TypeError: write() argument must be str, not bytes
https://lesguillemets.github.io/blog/2014/12/01/python3-cgi-typeerror.html
こちらの記事を参考にしたり色々調べた結果、現在のコードに落ち着いた。
今でもまだ何が悪いのかがわかっていない。
python cgiについて
https://docs.python.org/3/library/cgi.html
参考記事
Vue.js axios を利用した API の使用
https://jp.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html
サーバーエラーレスポンス一覧
https://developer.mozilla.org/ja/docs/Web/HTTP/Status
apache Apache Tutorial: CGI による動的コンテンツ
https://httpd.apache.org/docs/2.4/ja/howto/cgi.html
axios CDN
https://cdnjs.com/libraries/axios
Hatena Blog
Docker + Alpine3.5 + Apache2.4 + Python3.6で、フォームのデータを標準モジュールcgiで受け取ってみた
https://thinkami.hatenablog.com/category/Python?page=1494886074
Python3 + cgi.FieldStorage で typerror
https://lesguillemets.github.io/blog/2014/12/01/python3-cgi-typeerror.html
Python Common Gateway Interface support
https://docs.python.org/3/library/cgi.html