Python 3 – CGI编程
通用网关接口(Common Gateway Interface,简称CGI)是一组标准,用于定义Web服务器和自定义脚本之间如何交换信息。CGI规范目前由NCSA维护。
什么是CGI?
- 通用网关接口(Common Gateway Interface,简称CGI)是用于外部网关程序与信息服务器(如HTTP服务器)进行接口操作的标准。
-
当前版本是CGI/1.1,CGI/1.2正在制定中。
Web浏览
为了理解CGI的概念,让我们看看当我们单击超链接以浏览特定Web页面或URL时会发生什么。
- 您的浏览器联系HTTP Web服务器,并要求URL,即文件名。
-
Web服务器解析URL并查找文件名。如果找到该文件,Web服务器则将其发送回浏览器;否则Web服务器会发送一个错误消息,说明您请求了错误的文件。
-
Web浏览器接收来自Web服务器的响应,并显示接收到的文件或错误消息。
然而,可以设置HTTP服务器,使其在请求特定目录中的文件时,不会将该文件发送回去;相反,它会将其作为程序执行,将该程序输出的任何内容发送回浏览器以显示。这个功能称为通用网关接口(CGI),而这些程序称为CGI脚本。这些CGI程序可以是Python脚本、PERL脚本、Shell脚本、C语言或C++语言程序等。
CGI架构图
Web服务器支持和配置
在进行CGI编程之前,请确保您的Web服务器支持CGI,并已配置为处理CGI程序。由HTTP服务器执行的所有CGI程序都保存在预先配置的目录中。该目录称为CGI目录,按照惯例,它的名称为/var/www/cgi-bin。默认情况下,Linux服务器配置为只运行在/var/www/cgi-bin目录中的脚本。如果您想指定其他任何目录来运行您的CGI脚本,请在httpd.conf文件中注释以下行−
<Directory "/var/www/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
<Directory "/var/www/cgi-bin">
Options All
</Directory>
这里我们假设您的Web服务器已经成功运行,并且您可以运行任何其他的CGI程序(如Perl或Shell脚本等)。
第一个CGI程序
这是一个简单的链接,链接到一个名为 hello.py 的CGI脚本。该文件保存在/var/www/cgi-bin目录中,内容如下。在运行CGI程序之前,请确保您已使用UNIX命令 chmod 755 hello.py 改变文件的模式来使其可执行。
#!/usr/bin/python
print ("Content-type:text/html\r\n\r\n")
print ('<html>')
print ('<head>')
print ('<title>Hello Word - First CGI Program</title>')
print ('</head>')
print ('<body>')
print ('<h2>Hello Word! This is my first CGI program</h2>')
print ('</body>')
print ('</html>')
注意 − 脚本中的第一行必须是Python可执行程序的路径。在Linux中,它应该是#!/usr/bin/python3。
在您的浏览器中输入以下URL
http://localhost:8080/cgi-bin/hello.py
## 你好世界!这是我的第一个CGI程序
这个hello.py脚本是一个简单的Python脚本,它在标准输出文件(即屏幕)上输出其输出。有一个重要的并且额外的特性可用于要打印的第一行 Content-type:text/html\r\n\r\n 。这一行被发送回浏览器,并指定要在浏览器屏幕上显示的内容类型。
现在您必须已经了解了CGI的基本概念,并且可以使用Python编写许多复杂的CGI程序。此脚本还可以与任何其他外部系统交互,以交换信息,例如RDBMS。
HTTP标头
行 Content-type:text/html\r\n\r\n 是HTTP头的一部分,用于发送到浏览器以了解内容。所有HTTP头将采用以下形式 –
HTTP字段名称:字段内容
例如:
内容类型:text/html\r\n\r\n
您在CGI编程中经常使用的其他几个重要的HTTP头。
序号 | 头文件和描述 |
---|---|
1 | Content-type: 定义返回文件的格式的MIME字符串。Example is Content-type:text/html |
2 | Expires: Date 信息失效的日期。它由浏览器用于决定何时需要刷新页面。有效的日期字符串格式为 01 Jan 1998 12:00:00 GMT。 |
3 | Location: URL 返回代替请求的URL。您可以使用此字段将请求重定向到任何文件。 |
4 | Last-modified: Date 资源的最后修改日期。 |
5 | Content-length: N 返回的数据的长度(以字节为单位)。浏览器使用此值报告文件的估计下载时间。 |
6 | Set-Cookie: String 设置通过 字符串 传递的cookie。 |
CGI环境变量
所有CGI程序都可以访问以下环境变量。在编写任何CGI程序时,这些变量都扮演着重要角色。
序号 | 变量名及描述 |
---|---|
1 | CONTENT_TYPE 内容的数据类型。当客户端向服务器发送附加内容(例如,文件上传)时使用。 |
2 | CONTENT_LENGTH 查询信息的长度。仅在POST请求中可用。 |
3 | HTTP_COOKIE 以键值对的形式返回已设置的cookie。 |
4 | HTTP_USER_AGENT User-Agent请求头字段包含有关发起请求的用户代理的信息。这是指的 web 浏览器的名称。 |
5 | PATH_INFO CGI脚本的路径。 |
6 | QUERY_STRING 与GET方法请求一起发送的URL编码信息。 |
7 | REMOTE_ADDR 发出请求的远程主机的IP地址。这对于日志记录或身份验证非常有用。 |
8 | REMOTE_HOST 发出请求的主机的完全限定名称。如果不可用,则可以使用 REMOTE_ADDR 获取 IP 地址。 |
9 | REQUEST_METHOD 用于发出请求的方法。最常见的方法是 GET 和 POST。 |
10 | SCRIPT_FILENAME CGI脚本的完整路径。 |
11 | SCRIPT_NAME CGI脚本的名称。 |
12 | SERVER_NAME 服务器的主机名或IP地址。 |
13 | SERVER_SOFTWARE 服务器正在运行的软件的名称和版本。 |
下面是一个小的CGI程序,用于列出所有的CGI变量。
#!/usr/bin/python
import os
print ("Content-type: text/html\r\n\r\n");
print ("<font size=+1>环境变量</font><\br>");
for param in os.environ.keys():
print ("<b>%20s</b>: %s<\br>" % (param, os.environ[param]))
GET和POST方法
您可能遇到许多情况,需要将某些信息从您的浏览器传递到Web服务器,最终传递到您的CGI程序。浏览器最常用的两种方法是GET方法和POST方法。
使用GET方法传递信息
GET方法将编码的用户信息附加到页请求。页和编码信息由?字符分隔,如下所示−
http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2
- GET方法是从浏览器向Web服务器传递信息的默认方法,在浏览器的Location:框中产生一个长字符串。
-
如果您要传递密码或其他敏感信息到服务器,则永远不要使用GET方法。
-
GET方法有大小限制:请求字符串中只能发送1024个字符。
-
GET方法使用QUERY_STRING头发送信息,并可以通过QUERY_STRING环境变量在您的CGI程序中访问它。
您可以通过简单地连接键和值对以及任何URL来传递信息,也可以使用HTML