一、概述
CGI(Common Gateway Interface)也叫通用网关接口,它是一个web服务器主机提供信息服务的标准接口,只要遵循这个接口,web服务器就能获取客户端提交的信息,转交给服务端的CGI程序进行处理,然后将处理结果返回给客户端。
CGI通讯由两部分组成:一部分是用户的浏览器显示的页面,也就是html页面,另一部分是运行在服务器上的CGI程序。
二、CGI架构
CGI是Web服务器和一个独立的进程之间的协议,它会把HTTP请求 Request 的 Header 头设置成进程的环境变量,HTTP 请求的 Body 正文设置成进程的标准输入,进程的标准输出设置为HTTP响应 Response,包含 Header 头和 Body 正文。
三、Web服务器环境搭建(windows)
本例使用Apache2.4.x + Python3.x + windows搭建Web服务器实现CGI编程
3.1、 安装Apache2.4.x
官方下载地址:Apache2.4.x下载地址
需要:VC14 需要下载Microsoft Visual C++ 2015,官方地址为:Microsoft Visual C++ 2015
3.2、 Apache2.4.x配置(配置路径:Apache24–>conf–>httpd.conf)
A、配置Apache文件的根目录:设置SRVROOT根目录为电脑端Apache的存放路径。为方便后期修改方便,可利用引用“${SRVROOT}”的方式来书写配置,即:
注:Apache2.2.x版本修改“ServerRoot”
B、修改端口配置:默认端口80,此处改为1024
C、设置python文档的存储路径,以便Python解释器能够找到它们(即设置访问权限),此处路径设置为“D:\Apache24\cgi-bin”,找到如下内容:
修改为:
配置文件:
<Directory "${SRVROOT}/cgi-bin">
AllowOverride None
Options Indexes FollowSymLinks ExecCGI
Require all granted
Require host ip
</Directory>
注意:httpd.conf里面还有一个标签,此处不用改:
D、添加.py 后缀:在 AddHandler 中添加 .py 后缀,这样就可以访问 .py 结尾的 python 脚本文件
E、开启cgi_module modules/mod_cgi.so模块(即去掉模块前的注释#):
F:启动apach服务器(Apache24\bin目录下)
Apache24\bin目录下,使用“httpd -k install -n apache”安装Apache主服务,然后输入“httpd –k start”开启Apache服务(管理员身份运行DOS)
G:编写.py脚本
#!D:/Python/Python37/python.exe
# -*- coding: utf-8 -*-
print ("Content-type:text/html\n\n")
print # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>this ia a CGI program !!!</title>')
print ('</head>')
print ('<body>')
print ('<h2>this ia a CGI program !!!</h2>')
print ('</body>')
print ('</html>')
脚本说明:
1、第一行是申明电脑端解释器的位置,注意一定要写第一行,这是python的格式规范
2、因电脑端安装的是Python3.7,输出语句print("")一定要加括号,一定要注意,不然之后会报500错误
3、第三行的print (“Content-type:text/html\n\n”),这是声明格式,此处注意,其中的“\n\n”,两个“\n”,一个都不能少,少了也会报500错误
4、ScriptAlias /cgi-bin/ "${SRVROOT}/cgi-bin/"设置了解释器查找.py文件的方法
H:浏览器输入“http://localhost:1024/cgi-bin/hello.py”即可运行hello.py文件
I:修改cgi-bin中.py文件路径为任意位置:修改httpd.conf中和ScriptAlias下路径
J:修改Apache中.html文件存放路径:修改httpd.conf中DocumentRoot和的配置,即:
四、CGI编程解析
4.1、 HTTP头部
上文中hello.py文件中的" Content-type:text/html"为HTTP头部的一部分,它会发送给浏览器告诉浏览器文件的内容类型。
HTTP头部格式:HTTP 字段名: 字段内容
如:Content-type:text/html
CGI程序中HTTP头部经常使用的信息如下:
头部信息 | 描述 |
---|---|
Content-type: | 请求的与实体对应的MIME信息,例如: Content-type:text/html |
Expires: Date | 响应过期的日期和时间 |
Location: URL | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 |
Last-modified: Date | 请求资源的最后修改时间 |
Content-length: N | 请求的内容长度 |
Set-Cookie: String | 设置Http Cookie |
4.2、 CGI环境变量
所有的CGI程序都会接收以下环境变量,这些环境变量在CGI程序中发挥了重要的作用,具体如下:
环境变量名 | 描述 |
---|---|
CONTENT_TYPE | CONTENT_TYPE的值指示所传递来的信息的MIME类型。一般情况下该变量的值是:application/x-www-form-urlencoded,表示数据来自于HTML表单 |
CONTENT_LENGTH | 假如服务器与CGI程序信息的传递方式是POST,这个环境变量即从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。 |
HTTP_COOKIE | 客户机内的 COOKIE 内容 |
HTTP_USER_AGENT | 提供包含了版本数或其他专有数据的客户浏览器信息 |
PATH_INFO | 这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。 |
QUERY_STRING | 如果服务器与CGI程序信息的传递方式是GET,这个环境变量的值即所传递的信息。这个信息经跟在CGI程序名的后面,两者中间用一个问号’?'分隔。 |
REMOTE_ADDR | 这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识,可以在CGI程序中用它来区分不同的Web客户机。 |
REMOTE_HOST | 这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。 |
REQUEST_METHOD | 提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。 |
SCRIPT_FILENAME | CGI脚本的完整路径 |
SCRIPT_NAME | CGI脚本的的名称 |
SERVER_NAME | 这是你的 WEB 服务器的主机名、别名或IP地址。 |
SERVER_SOFTWARE | 这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix) |
#!D:/Python/Python37/python.exe
import os
# -*- coding: utf-8 -*-
print ("Content-type:text/html\n\n")
print # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>this ia CGI environment variable</title>')
print ('</head>')
print ('<body>')
print ('<h2>this ia CGI environment variable</h2>')
print ("<ul>")
for key in os.environ.keys():
print ("<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key]))
print ("</ul>")
print ('</body>')
print ('</html>')
浏览器输入“http://localhost:9999/cgi-bin/ZX_02_Environment_Variable.py”,结果如下:
4.3、 CGI使用GET方法传输数据
GET方法发送编码后的用户信息到服务端,数据信息包含在请求页面的URL上,以"?"号分割
GET请求需注意如下内容:
1、GET 请求可被缓存
2、GET 请求保留在浏览器历史记录中
3、GET 请求可被收藏为书签
4、GET 请求不应在处理敏感数据时使用
5、GET 请求有长度限制
6、GET 请求只应当用于取回数据
A、GET方法处理URL链接
步骤:
1、导入cgi库
import cgi
2、创建 FieldStorage 的实例化
form = cgi.FieldStorage()
3、通过表单获取数据
key = form.getvalue('value')
get_url.py文件内容:
#!D:/Python/Python37/python.exe
# 导入cgi处理模块
import cgi
# 实例化FieldStorage,代表整个表单
form = cgi.FieldStorage()
# 通过表单获取数据
name = form.getvalue("name")
pwd = form.getvalue("pwd")
print("Content-type:text/html\n\n")
print
print('<html>'