python CGI 编程实践

文章更新于:2020-03-05

注1:安装 python 参见: python 的安装使用和基本语法
注2:配置 web 环境参见: Windows&linux使用集成环境搭建 web 服务器
注3:linux 配置 CGI参见:linux 配置 python3 CGI
注4:Windows配置 CGI 参见:windows环境下利用python进行CGI配置

一、Web服务器的支持与配置

在进行CGI编程之前,请确保Web服务器支持CGI,它被配置为处理CGI程序。所有对由HTTP服务器执行的CGI程序保存在一个预先配置的目录。此目录被称为CGI目录,并按照惯例被命名为/var/www/cgi-bin目录。按照惯例,CGI文件具有扩展名为.cgi,但文件扩展名可以为Python语言脚本 .py。

//原文出自【易百教程】,非商业请保留原文链接:https://www.yiibai.com/python/python_cgi_programming.html

默认情况下,Linux服务器被配置为只运行在在/var/www/cgi-bin目录中的脚本。如果想在其他目录运行CGI程序,需要更改配置文件。有两种方法。

1、设置 ScriptAlias(方法一)

/etc/httpd/conf/httpd.conf主配置文件中,找到ScriptAlias所在行,添加你所需要的目录,如:

ScriptAlias  /test/  "/var/www/test/"

上述代码的 /test/ 是你web访问的路径, /var/www/test/ 是你web访问路径实际对应的本地路径。

配置完成之后,保存退出,重启 httpd 服务即可。

注1:以上路径配置之后,该目录下所有文件都视为CGI程序处理,如果这时你放一个HTML文件进去,访问的时候会出错。
注2:路径最后的/不能少,少了会报错。

2、配置对应的目录(方法二)

在主配置文件中写入以下内容:

# 下面的目录为你要设定的目录
<Directory "/var/www/test/">
    Options ExecCGI
</Directory>

# 找到 AddHandler 所在行,加入你要添加的后缀,这里添加 .py
AddHandler cgi-script .cgi .py

经过这样设定后,在此目录下以 .py 结尾的文件当做 cgi 程序处理,其他文件正常处理。

二、 CGI 程序实践

1、声明程序解释器和编码

CGI 程序需要在程序开头声明程序解释器,程序解释器也就是程序用什么来执行。

以python举例:

Windows声明:#! "D:program|python37python.exe",注意,一定要声明到.exe文件。
Linux声明:#! /usr/bin/env python3 ,也可使用 #!/usr/bin/python3

然后第二行声明程序编码:# -*- coding:UTF-8 -*-,注意,程序编码只在前两行范围内声明有效。

2、输出响应头部(HTTP报文头)信息

比如说:
print("Content-type:text/html")

一些重要的HTTP头如下:

报头 描述
Content-type: 返回MIME字符串,定义文件的格式。例如Content-type:text/html
Expires:Date 日期的信息变为无效。这应该被使用的浏览器,以决定当一个页面需要刷新。有效日期字符串应该是格式1998年1月1日12:00:00 GMT。
Location: URL 应该返回替代请求URL的URL。可以使用此字段来重定向请求到任何文件。
Last-modified: Date 资源的最后修改的日期。
Content-length: N 数据的长度,以字节为单位被返回。浏览器使用这个值来报告预计下载时间的文件。
Set-Cookie:String 通过设置该字符串传递cookie

输出完报文头以后要输出1-2个空行 print(" "),以告诉服务器报头部分结束,否则会报错。

3、CGI环境变量。

所有的CGI程序都可使用以下环境变量:

环境变量 描述
CONTENT_TYPE 内容的数据类型。当客户端发送内容附加到服务器使用。例如,文件上传等。
CONTENT_LENGTH 查询信息的长度。它仅适用于POST请求。
HTTP_COOKIE 返回键和值对的形式设置Cookie。
HTTP_USER_AGENT 用户代理请求头字段包含有关用户代理发起请求信息。网络浏览器的名称。
PATH_INFOTCGI 脚本的路径。
QUERY_STRING 被发送GET方法请求URL编码的信息。
REMOTE_ADDR 远程主机发出请求的IP地址。这可以是用于记录或用于认证的目的是有用的。
REMOTE_HOST 发出请求的主机的完全合格的名称。如果该信息不可用,则REMOTE_ADDR可用于获得IP地址。
REQUEST_METHOD 该方法用于制造要求。最常用的方法是GET和POST。
SCRIPT_FILENAMECGI 脚本的完整路径。
SCRIPT_NAMECGI 脚本的名称。
SERVER_NAME 服务器的主机名或IP地址
SERVER_SOFTWARE 软件服务器运行的名称和版本。

程序使用这些变量需要导入os包,程序举例:

#! /usr/bin/env python
# -*- coding:UTF-8 -*-
print('Content-Type: text/html; charset=utf-8
')

import os
print("你好")
print("<br>你的IP是:%s"%os.environ['REMOTE_ADDR'])

4、GET / POST 方法

GET 方法适用于显式传送信息,内容会出现在 URL 中,有 1024 字符的长度限制。
POST 方法没有大小限制,采用隐式传送,所以比较安全。

举个例子:
GET:访问 /cgi-bin/test.py?key=hello,将会传递值为hellokeycgi·程序。
POST:访问 /cgi-bin/test.py,并传递值给cgi程序。

二者可以使用同一个脚本进行接收,cgi程序可以使用接收并处理这个值。

#! /usr/bin/env python3
# -*- utf-8 -*-
# 导入处理模块
import cgi, cgitb

# 创建FieldStorage实例
form = cgi.FieldStorage()

# 进行赋值操作
getvalue = form.getvalue('key')

# 输出报文头并换行结束头部
print("Content-type:text/html
")

# 输出HTML代码
print("<html>")
print("<head>")
print("<title>Get value program!</title>")
print("</head>")
print("<body>")
print("You have put the value: %s"%getvalue)
print("</body>")
print("</html>")

5、在 CGI 程序中使用 cookies

HTTP 是无状态协议,但如果你想让访问者从你网站的一个页面跳转到另一个页面的时候保持登录状态,就可以使用cookies来实现。

cookies 是服务器请求在访问者电脑硬盘上保存的一段简单文本,这段文本标识了访问者的身份。

当访问者从一个页面跳转到另一个页面的时候,浏览器会带上这段文本,服务器检查这段文本来确定访问者的身份。

cookies 是5个可变长的纯文本数据。

描述
Expires cookie过期的时间,如果置空则表示退出浏览器即过期
Domain cookie在你网站的哪些域名可以生效
Path 在你网站的有效的域名上哪些网页路径可以生效,如果置空则表示所有都生效
Secure 规定是否通过安全的 HTTPS 连接来传输 cookie
Name=Value cookies的键值对信息,也就是cookie的名称和值,可以设置多个

举个例子:

print "Set-Cookie:UserID=mingzi;"
print "Set-Cookie:Password=mima123;"
print "Set-Cookie:Expires=Tuesday, 3-Dec-2020 08:30:00 GMT";"
print "Set-Cookie:Domain=www.xxxx.com;"
print "Set-Cookie:Path=/test;"
print "Content-type:text/html"

那么CGI如何获取cookie呢?

#!/usr/bin/python
# -*- utf-8 -*-
print("Content-type:text/html
")

# Import modules for CGI handling 
from os import environ
import cgi, cgitb

if environ.has_key('HTTP_COOKIE'):
   for cookie in map(strip, split(environ['HTTP_COOKIE'], ';')):
      (key, value ) = split(cookie, '=');
      if key == "UserID":
         user_id = value

      if key == "Password":
         password = value

print "User ID  = %s" % user_id
print "Password = %s" % password

三、Enjoy!

原文地址:https://www.cnblogs.com/amnotgcs/p/12694358.html