Python3 cgi实现与web前端交互

python 3 CGI 实现前端交互(基于Docker)

前言

​ 最近呢,因为考研复习比较紧张,就很少写博文了,不过学习都不能停哈,这个胡搞乱搞其实来自考研的一个需求,因为本人英语不是特别好,然后学习了一个方法就是,看文章写答案,但是不要对答案,这个不要对答案的意思呢,是找一个小伙伴帮你对,但是不告诉你错在哪里,然后自己慢慢摸索,直到全部循环到正确为止·····Balala,因为实现这个方法需要一个人给查吗,暑假我的小伙伴都回家了,自习室的我也不太好意思麻烦人家,最终我就忽然想到,我为什么不自己写一个程序帮我查呢?(PS:这个程序本来是自己用的,我把他扔到了我的服务器上,然后我用手机的SSH软件连接。不过呢,这两天跟一个在家里的小伙伴聊,小伙伴觉得不错,也想用一下,哎,为了造福人民大众,今天下午给自己放个假,happy一下,把他给扔到web页面,和后面的python交互,B/S架构牛批!)

1 python cgi 部署

​ 如果想把python扔到web页面,感觉有几种选择,第一用框架,直接上个django,flask。这个太重量级了,后来上网上查了查,发现CGI还不过,简单粗暴啊,我需求也不高,所以就打算用这个了,说干就干,开撸!

​ 不过cgi的安装就有点恶心了,我的web容器是nginx的,nginx默认是不支持cgi的。(但是呢可以通过一些方法使得其支持,在网上查阅了一些资料,可以通过fastcgi构建) 不过这个服务器上本身就跑着我的一个博客,虽然说最近迁移到github上面了啊。

但是安装这个cgi支持,最简单粗暴的方法就是apache+cgi。哈哈,为了复习复习docker,我们那就在docker里面来玩一下然后映射到外面的端口开着不就行了嘛。

好啦,我们pull一个docker镜像 直接pull个linux系统的docker(别问我为什么不直接弄一个apache的下来,一会还得装python)

  • 1563878839928

直接docker开一个容器。

然后 docker attach id 进入容器

然后输入命令

1
2
3
apt-get update &&  apt-get upgrade #不知道这个景象放了多久了好像是ubuntu14版本的,先更新个源
apt-get install -y apache2 #安装apache
/etc/init.d/apache2 start #启动服务
  • 1563879663700

由于我们映射到外部端口了,这里我们访问8080,成功!

接下来我们可以进行cgi的配置了。

由于我们的docker镜像没有装python,这里呢,我们需要装python

输入

1
apt-get install -y python3

进入apache2的安装目录,看到

” mods-enabled “ 和 ” mods-available “ 这里面才发现一个问题,apache变了(可能是我搞乱了或者out了),不像从前找httpd.conf了

现在是这两个文件夹

mods-enabled 默认开启的功能

mods-available 默认不开启的功能

我们的CGI是默认不开启的,所以我们进入到下面的文件夹里面去开启一下

  • 1563881228792

找到文件。

1
2
3
ln -s /etc/apache2/mods-available/cgid.conf /etc/apache2/mods-enabled/cgid.conf
ln -s /etc/apache2/mods-available/cgid.load /etc/apache2/mods-enabled/cgid.load
ln -s /etc/apache2/mods-available/cgi.load /etc/apache2/mods-enabled/cgi.load

输入以上三条命令建立软连接,这个软连接就相当于我们windows的快捷方式。

1
/etc/init.d/apache2 restart

然后重启apache服务

  • 1563881500980

发现出现了这个文件。

然后我们vim 打开这个文件,配置一下cgi的目录。

  • 1563881715715

我们修改

Scruptalias 最后面的内容/usr那里,我这里是修改好的了,这个其实就是指定一个你cgi脚本的目录,当你在浏览器访问/cgi-bin/系统就会自动找到这个目录里面去。

然后别忘了重启Apache服务

  • 1563881836341

我们到指定目录下建立一个cgi的文件夹

然后进入创建一个.py文件编辑

  • 1563882514555

比如说我这里,我们这里就成功的编辑了这个文件了,然后通过web访问,发现web页面已经回显结果了。

这里特别要注意一定要加 第一行

告诉用什么解释器

1
#!/usr/bin/env python3.6

否则http就会报500,另外,你应该给这个程序755权限。

2 创建前端页面实现与后端交互

​ 由于我的页面只做于考研查阅资料用什么CSS+JS美工啥的我也没做,就凑活用用吧先。

其实也很简单,首先呢我先写个前端页面,很简单的。然后放到apache指定的网站根目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>考研英语阅读检查@青花</title>
<style>
body{
background-image: url(https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=358446648,1506816524&fm=26&gp=0.jpg);
background-size: 100%;
}
</style>
</head>
<body >
<br>
<h1 align=center>考研英语阅读错误个数检查</h1>
<h3 align=center>Tips:请您按照提示输入,先输入年份比如说您想查阅1998年的就输入y98,2000的就输入y00,2010的就输入y10。</h3>
<h3 align=center>然后再根据您的作答输入答案(如果只检查单题在其他题目作答地方不输入即可),比如说答第一题,就在第一</h3>
<h3 align=center>题的地方输入&nbsp&nbspa,a,a,a&nbsp&nbsp中间用逗号隔开,点击提交系统会将结果返还给您。后台程序写的潦草,可能会有一些输</h3>
<h3 align=center>页面不能正常回显,存在一些bug需要解决,我会在后面有时间来修复完善,请您谅解。</h3>

<form action="/cgi-bin/get.py" method="post" align=center>
<br>
<br>
查阅年份:<input type="text" name="data_1" >
&nbsp&nbsp&nbsp&nbsp&nbsp
&nbsp第一题答案:<input type="text" name="data_2" >
<br>
<br>
第二题答案:<input type="text" name="data_3">
&nbsp&nbsp&nbsp&nbsp
第三题答案:<input type="text" name="data_4">
<br>
<br>
第四题答案: <input type="text" name="data_5">
&nbsp&nbsp&nbsp&nbsp
第五题答案:<input type="text" name="data_6">
<br>
<br>
<input type="submit" value="提交" />
</form>
</body>
</html>

​ 效果图

  • 1563941842023

然后我们测试输入即可。

其实只要学过其他的什么php,asp,jsp应该都明白就是html表单提交给我们程序处理吗。然后我们程序处理返回一个结果。

然后呢我们利用cgi写一个后台处理的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/env python3.6

import cgi
import cgitb




if __name__=="__main__":
#####

y98=[["c","d","d","c"],["a","b","b","a"],["c","d","a","a"],["b","c","d","c"],["b","b","d","c"]]
y99=[["b","c","a","d"],["a","c","d","b"],["b","d","c","a"],["b","c","d","a"],["a","b","d","a"]]
y00=[["c","d","b","a"],["c","b","a","d"],["b","a","c","d"],["b","d","c","a"],["a","c","d","b"]]
y01=[["d","b","a","c"],["c","a","d","a"],["b","d","c","a"],["c","a","d","b"],["b","b","c","d"]]
y02=[["c","b","d","d","a"],["c","c","d","b","c"],["b","d","d","a","a"],["b","c","b","a","d"]]
y03=[["b","a","c","b","d"],["a","b","b","a","d"],["c","d","c","b","a"],["c","a","b","d","c"]]
y04=[["c","a","d","b","c"],["a","d","c","b","d"],["d","a","b","a","c"],["c","a","d","b","c"]]
y05=[["c","b","a","c","b"],["c","d","a","d","b"],["a","c","d","d","a"],["b","d","a","b","c"]]
y06=[["c","a","c","d","b"],["a","b","c","d","d"],["c","a","c","d","b"],["d","b","d","b","a"]]
y07=[["c","b","a","d","c"],["d","c","a","a","b"],["c","b","d","c","b"],["d","a","b","a","d"]]
y08=[["a","d","c","b","d"],["d","c","a","a","b"],["a","c","b","d","c"],["d","b","c","a","b"]]
y09=[["c","d","a","d","a"],["a","c","d","a","b"],["d","b","b","c","c"],["b","b","d","a","c"]]
y10=[["b","a","c","a","b"],["c","b","c","b","a"],["b","d","a","c","c"],["a","a","c","c","d"]]
y11=[["c","b","d","b","a"],["b","d","c","a","c"],["d","c","b","a","a"],["c","d","a","d","b"]]
y12=[["d","b","a","c","d"],["c","d","a","d","a"],["a","b","b","d","c"],["c","d","b","c","a"]]
y13=[["b","d","a","d","c"],["b","d","c","a","d"],["b","a","d","c","c"],["c","c","d","a","b"]]


####
mydi={"y98":y98,"y99":y99,"y00":y00,"y01":y01,"y02":y02,"y03":y03,"y04":y04,"y05":y05,"y06":y06,"y07":y07,"y08":y08,"y09":y09,"y10":y10,"y11":y11,"y12":y12,"y13":y13}
answer=[]
f=cgi.FieldStorage()
tag=f.getvalue('data_1')
an1=f.getvalue('data_2')
an2=f.getvalue('data_3')
an3=f.getvalue('data_4')
an4=f.getvalue('data_5')
an5=f.getvalue('data_6')
answer.append(str(an1))
answer.append(str(an2))
answer.append(str(an3))
answer.append(str(an4))
answer.append(str(an5))
##
#answer1=[["c","d","d","c"],None,None,None,None]
for i in range(len(answer)):
if answer[i]!='None':
answer[i]=str.split(answer[i],",")
if answer[i]=='None':
answer[i]=str.split("e,e,e,e,",",")

y=mydi["y98"]
flag=0
for i in range(len(y)):
for j in range(len(y[i])):
if y[i][j]==answer[i][j]:
flag=flag+1


print("Content-Type:text/html\n\n")
print("<html>")
print("<head>")
print("<title>result</title>")
print("<script>")
print("function tz(){")
print(" window.location.href='http://139.224.115.186:8080'")
print("}")
print("</script>")
print("<style>")
print("body {")
print(" background-image : url(http://img18.3lian.com/d/file/201711/27/76041b1cf0ee94a40179305554f1eda7.png)")
print(";")
print(" background-size: 100% }")
print("</style>")
print("</head>")
print("<body>")
print("<h1 align=center>The number of correct answer you gave<br>")
print(str(flag))
print("</h1><br>")
print("<div align=center>")
print("<button onclick=tz()>return</button>")
print("</div>")
print("</body>")
print("</html>")

上面代码有些乱,因为一开始因为linux还有windows文件编码不一样,我一开始直接从windows拷贝过去的,结果linux一直报错,最后用vim重写的,所以都写一块了很乱,没有写函数。

其实核心思想说一下,就是我们调用这个python处理,然后输出一个前端页面再给前端,其中包含着我们的结果就行了。

我们来测试一下

  • 1563942442214

发现成功,返回结果正确。

3 总结

​ 这次乱搞弄了一个与web前端交互的python cgi后端程序,也算是对这方面有了一些简单的了解,然后通过动手操作也发现了好多坑,代码能在linux上写就在上面写,虽然说是shell界面,但是vim用的6也可能不比别的差,我这种在windows上用IDE用多了,vim就显得很生疏,不过最终问题也解决了。这个里面反正还是有几点需要注意的

  1. 注意关联文件开启cgi功能
  2. 注意给予文件权限,以及制定python解释器执行
  3. 注意不同平台编码问题