发布时间2024-10-04 浏览次数:0
发布时间:2024-10-04 浏览次数:0 文章来源:原创
CGI目前由NCSA维护,NCSA对CGI的定义如下:
CGI(Common Gateway Interface),通用网关接口,是运行在HTTP服务器等服务器上的程序,提供与客户端HTML页面的接口。
网页浏览
为了更好地理解CGI 的工作原理,我们可以从点击网页上的链接或URL 的过程开始:
1. 使用浏览器访问URL 并连接到HTTP Web 服务器。
2、Web服务器收到请求信息后,会解析URL并检查所访问的文件是否存在于服务器上。如果文件存在,则返回文件内容,否则返回错误信息。
3. 浏览器从服务器接收信息并显示接收到的文件或错误消息。
CGI程序可以是Python脚本、PERL脚本、SHELL脚本、C或C++程序等。
CGI架构图
Web 服务器支持和配置
在执行CGI 编程之前,请确保您的Web 服务器支持CGI 并且已配置CGI 处理程序。
HTTP服务器执行的所有CGI程序都保存在预先配置的目录中。该目录称为CGI 目录,按照惯例,它的名称为/var/www/cgi-bin。
CGI 文件具有.cgi 扩展名,python 也可以使用.py 扩展名。
默认情况下,Linux 服务器配置在/var/www 中的cgi-bin 目录中运行。
如果想指定其他目录运行CGI脚本,可以修改httpd.conf配置文件,如下:
目录“/var/www/cgi-bin”
允许覆盖无
选项ExecCGI
订单允许、拒绝
允许所有
/目录
目录“/var/www/cgi-bin”
选项全部
/目录
第一个CGI 程序
我们使用Python 创建第一个CGI 程序。文件名为hellp.py。该文件位于/var/www/cgi-bin 目录中。内容如下。修改文件的权限为755:
#!/usr/bin/python
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”
print 'titleHello Word - 第一个CGI 程序/标题'
打印“/头”
打印“正文”
打印'h2Hello Word!这是我的第一个CGI 程序/h2'
打印“/body”
打印'/html'
当通过浏览器访问上述程序时,显示结果如下:
你好词!这是我的第一个CGI 程序
这个hello.py 脚本是一个简单的Python 脚本。脚本'Content-type:text/html\r\n\r\n'的第一个输出内容被发送到浏览器,告诉浏览器显示的内容类型是'text/html'。
HTTP 标头
hello.py 文件内容中的'Content-type:text/html\r\n\r\n' 是HTTP header 的一部分,它会被发送到浏览器,告诉浏览器该文件的内容类型。
HTTP头的格式如下:
HTTP字段名称: 字段内容
例如
内容类型: 文本/html\r\n\r\n
下表介绍了CGI程序中HTTP头中常用的信息:
头
描述
Content-type: 请求的实体对应的MIME 信息。例如: 内容类型:text/html
Expires: Date 响应过期的日期和时间
Location: URL 用于将接收者重定向到非请求URL 的位置,以完成请求或识别新资源。
Last-modified: Date 所请求资源的最后修改时间
Content-length: N 请求的内容长度
Set-Cookie: 字符串设置Http Cookie
CGI环境变量
所有CGI 程序都会接收以下环境变量,这些变量在CGI 程序中发挥着重要作用:
变量名
描述
CONTENT_TYPE 此环境变量的值指示正在传递的信息的MIME 类型。目前环境变量CONTENT_TYPE一般为: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)
下面是一个简单的CGI脚本,输出CGI环境变量:
#!/usr/bin/python
导入操作系统
print 'Content-type: text/html\r\n\r\n';
print '字体大小=+1环境/字体\br';
对于os.environ.keys(): 中的参数
print 'b%20s/b: %s\br' % (param, os.environ[param])
GET 和POST 方法
浏览器客户端通过两种方法向服务器传递信息:GET方法和POST方法。
使用GET方法传输数据
GET 方法将编码后的用户信息发送到服务器。数据信息包含在请求页面的URL中,以“?”分隔,如下所示:
http://www.test.com/cgi-bin/hello.py?key1=value1key2=value2
关于GET 请求的一些附加说明:
GET请求可以被缓存
GET 请求保留在浏览器历史记录中
可以为GET 请求添加书签
处理敏感数据时不应使用GET 请求
GET 请求有长度限制
GET 请求只能用于检索数据
简单url 示例:GET 方法
下面是一个简单的URL,它使用GET 方法向hello_get.py 程序发送两个参数:
/cgi-bin/hello_get.py?first_name=ZARAlast_name=ALI
以下是hello_get.py文件的代码:
#!/usr/bin/python
# CGI处理模块
导入cgi、cgitb
# 创建FieldStorage的实例
形式=cgi.FieldStorage()
# 获取数据
名字=form.getvalue('名字')
姓氏=form.getvalue('姓氏')
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”
print 'titleHello - 第二个CGI 程序/标题'
打印“/头”
打印“正文”
print 'h2Hello %s %s/h2' % (名字, 姓氏)
打印“/body”
打印'/html'
浏览器请求输出:
你好扎拉·阿里
简单形式示例:GET 方法
下面是一个HTML 表单,它使用GET 方法向服务器发送两个数据。提交的服务器脚本也是hello_get.py文件。代码如下:
表单操作='/cgi-bin/hello_get.py'方法='get'
名字: 输入type='text' name='first_name' br /
姓氏: 输入type='text' name='last_name' /
输入类型='提交'值='提交'/
/形式
使用POST方法传递数据
使用POST方式向服务器传输数据更加安全可靠。一些敏感信息例如用户密码需要使用POST来传输数据。
下面也是hello_get.py,同样可以处理浏览器提交的POST表单数据:
#!/usr/bin/python
#引入CGI模块
导入cgi、cgitb
#创建FieldStorage实例
形式=cgi.FieldStorage()
# 获取表单数据
名字=form.getvalue('名字')
姓氏=form.getvalue('姓氏')
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”
print 'titleHello - 第二个CGI 程序/标题'
打印“/头”
打印“正文”
print 'h2Hello %s %s/h2' % (名字, 姓氏)
打印“/body”
打印'/html'
下面的表单通过POST方法向服务器脚本hello_get.py提交数据:
表单操作='/cgi-bin/hello_get.py'方法='post'
名字: 输入type='text' name='first_name'br /
姓氏: 输入type='text' name='last_name' /
输入类型='提交'值='提交'/
/形式
通过CGI程序传递复选框数据
复选框用于提交一个或多个选项数据。 HTML代码如下:
表单操作='/cgi-bin/checkbox.cgi'方法='POST'目标='_blank'
输入类型='复选框'名称='数学'值='on'/数学
输入类型='复选框'名称='物理'值='on'/物理
input type='提交' value='选择主题' /
/形式
以下是checkbox.cgi 文件的代码:
#!/usr/bin/python
#引入CGI处理模块
导入cgi、cgitb
# 创建FieldStorage的实例
形式=cgi.FieldStorage()
#接收字段数据
if form.getvalue('数学'):
math_flag='开'
否则:
math_flag='关闭'
如果form.getvalue('物理'):
物理标志='开'
否则:
物理标志='关闭'
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”
print 'titleCheckbox - 第三个CGI 程序/标题'
打印“/头”
打印“正文”
print 'h2 复选框数学为: %s/h2' % math_flag
print 'h2 CheckBox 物理值为: %s/h2' %physical_flag
打印“/body”
打印'/html'
通过CGI程序传递无线电数据
无线电仅将一项数据传递到服务器。 HTML代码如下:
表单操作='/cgi-bin/radiobutton.py'方法='post'目标='_blank'
输入类型='无线电'名称='主题'值='数学'/数学
输入类型='无线电'名称='主题'值='物理'/物理
input type='提交' value='选择主题' /
/形式
radiobutton.py脚本代码如下:
#!/usr/bin/python
# 导入CGI 处理模块
导入cgi、cgitb
# 创建FieldStorage实例
形式=cgi.FieldStorage()
# 从字段中获取数据
如果form.getvalue('subject'):
主题=form.getvalue('主题')
否则:
主题='未设置'
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”
print 'titleRadio - 第四个CGI 节目/标题'
打印“/头”
打印“正文”
print 'h2 选择的主题是%s/h2' % 主题
打印“/body”
打印'/html'
通过CGI程序传递Textarea数据
Textarea 将多行数据传递到服务器。 HTML代码如下:
表单操作='/cgi-bin/textarea.py'方法='post'目标='_blank'
文本区域名称='文本内容'列='40'行='4'
在此输入您的文字.
/文本区域
输入类型='提交'值='提交'/
/形式
textarea.cgi脚本代码如下:
#!/usr/bin/python
# 导入CGI 处理模块
导入cgi、cgitb
# 创建FieldStorage实例
形式=cgi.FieldStorage()
# 从字段中获取数据
如果form.getvalue('textcontent'):
text_content=form.getvalue('textcontent')
否则:
text_content='未输入'
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”;
print 'titleText 区域- 第五个CGI 程序/标题'
打印“/头”
打印“正文”
print 'h2 输入的文本内容为%s/h2' % text_content
打印“/body”
通过CGI程序传递下拉数据
HTML下拉框代码如下:
表单操作='/cgi-bin/dropdown.py'方法='post'目标='_blank'
选择名称='下拉'
选项值='数学' selectedMaths/选项
选项值='物理'物理/选项
/选择
输入类型='提交'值='提交'/
/形式
dropdown.py脚本代码如下:
#!/usr/bin/python
# 导入CGI 处理模块
导入cgi、cgitb
# 创建FieldStorage实例
形式=cgi.FieldStorage()
# 从字段中获取数据
如果form.getvalue('dropdown'):
subject=form.getvalue('下拉菜单')
否则:
主题='未输入'
打印'内容类型:text/html\r\n\r\n'
打印“html”
打印“头”
print 'titleDropdown Box - 第六个CGI 程序/标题'
打印“/头”
打印“正文”
print 'h2 选择的主题是%s/h2' % 主题
打印“/body”
打印'/html'
在CGI 中使用cookie
http协议的一大缺点就是无法确定用户的身份,这给程序员带来了很大的不便。
cookie功能的出现弥补了这个缺点。
当客户访问脚本时,所有cookies都会通过客户的浏览器将记录数据写入客户的硬盘上。客户下次访问该脚本时,检索数据信息,从而达到身份辨别的功能。 Cookie常用于密码判断。
Cookie 语法
http cookies的发送是通过http header实现的,早于文件的传输。 set-cookie 标头的语法如下:
Set-cookie:name=name;expires=date;path=path;domain=domain;secure
name=name: 需要设置cookie值(name不能使用';'和',')。使用';'分隔多个名称值。例如:名称1=名称1;名称2=名称2;名称3=名称3。
expires=date: Cookie有效期,格式:expires='Wdy,DD-Mon-YYYY HH:MM:SS'
path=path: 设置cookie支持的路径。如果path是路径,则cookie将对该目录下的所有文件和子目录生效。例如:path='/cgi-bin/'。如果path是一个文件,则cookie是指对该文件生效,例如:path='/cgi-bin/cookie.cgi'。
domain=domain: 对cookies有效的域名,例如:domain='www.chinalb.com'
secure: 如果给出此标志,则意味着cookie 只能通过具有SSL 协议的https 服务器传递。
接收cookies是通过设置环境变量HTTP_COOKIE来实现的。 CGI程序可以通过检索该变量来获取cookie信息。
Cookie 设置
Cookie的设置非常简单,Cookie会在http header中单独发送。以下示例在cookie 中设置用户ID 和密码:
前
#!/usr/bin/python
打印'Set-Cookie:UserID=XYZ;\r\n'
打印'Set-Cookie:Password=XYZ123;\r\n'
print 'Set-Cookie:Expires=2007 年12 月31 日星期二23:12:40 GMT';\r\n'
print 'Set-Cookie:Domain=www.ziqiangxuetang.com;\r\n'
打印'Set-Cookie:Path=/perl;\n'
打印'内容类型:text/html\r\n\r\n'
.其余HTML 内容.
上面的示例使用Set-Cookie头信息来设置Cookie信息,还可以选择性地设置Cookie的其他属性,例如过期时间Expires、域名、路径等。此信息设置在“Content-type:text/html\r\n\r\n”之前。
检索cookie信息
cookie信息检索页面非常简单。 Cookie 信息存储在CGI 环境变量HTTP_COOKIE 中。存储格式如下:
键1=值1;键2=值2;键3=值3.
下面是一个简单的CGI程序,用于检索cookie信息:
#!/usr/bin/python
# 导入CGI 处理模块
从操作系统导入环境
导入cgi、cgitb
如果environ.has_key('HTTP_COOKIE'):
对于地图中的cookie(strip, split(environ['HTTP_COOKIE'], ';')):
(键, 值)=split(cookie, '=');
如果键=='用户ID':
用户ID=值
if key=='密码':
密码=值
print '用户ID=%s' % user_id
print '密码=%s' % 密码
上述脚本的输出如下:
用户ID=XYZ
密码=XYZ123
文件上传示例:
要设置HTML 中上传文件的表单,需要将enctype 属性设置为multipart/form-data。代码如下:
html
身体
表单enctype='multipart/form-data'
操作='save_file.py'方法='post'
pFile: 输入类型='文件' name='文件名' //p
input type='提交' value='上传' //p
/形式
/身体
/html
#!/usr/bin/python
导入cgi、操作系统
导入cgitb; cgitb.enable()
形式=cgi.FieldStorage()
# 获取文件名
文件项=表单['文件名']
# 检查文件是否上传
如果文件项.文件名:
# 设置文件路径
fn=os.path.basename(文件项.文件名)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message='文件'' + fn + ''上传成功'
否则:
message='没有上传文件'
打印'''\
内容类型: 文本/html\n
html
身体
p%s/p
/身体
/html
''' (信息,)
如果您使用的系统是Unix/Linux,则必须更换文件分隔符。在window下,只需要使用open()语句即可:
fn=os.path.basename(fileitem.filename.replace('\\', '/' ))
文件下载对话框
如果我们需要向用户提供文件下载链接,并在用户点击该链接后弹出文件下载对话框,我们可以通过设置HTTP头信息来实现这些功能。函数代码如下:
#!/usr/bin/python
# HTTP 标头
打印'Content-Type:application/octet-stream; name=\'文件名\'\r\n';
打印'Content-Disposition:附件; filename=\'文件名\'\r\n\n';
# 实际文件内容将会被听到。
fo=open('foo.txt', 'rb')
str=fo.read();
打印字符串
# 关闭打开的文件
上一篇: 公司文件存储、共享、协同办公是否效率低下? 5分钟教你搭建私有云
下一篇: 返回列表
相关推荐
签证在手 旅途无忧发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
发布时间2024-10-04 浏览次数:0
用户评论
Python真的太棒了,想学习一下Python CGI来扩展网站功能!
有20位网友表示赞同!
CGI好像有点老旧的 технологии了吧?现在应该用什么代替呢?
有18位网友表示赞同!
学习Django框架也是了解Python CGI的好途径,可以试试看!
有17位网友表示赞同!
Python CGI编程文档看的头晕眼花…
有19位网友表示赞同!
最近想做一个网站,CGI似乎是个不錯的选择!
有18位网友表示赞同!
感觉Python CGI的应用场景还是很广泛啊,例如爬虫和自动化等。
有5位网友表示赞同!
打算试试用Python写一个简单的CGI脚本,看看效果如何。
有7位网友表示赞同!
有没有人分享一下Python CGI编程的一些常用资源?
有12位网友表示赞同!
学习Python要从基础开始,CGI应该算是进阶知识吧。
有10位网友表示赞同!
python_cgi 模块太难理解了!谁能帮忙解释一下吗?
有8位网友表示赞同!
想把Python的脚本封装成CGI程序,实现远程调用功能~!
有6位网友表示赞同!
CGI和Flask哪个更适合用于创建Web应用程序呢?
有16位网友表示赞同!
Python CGI 的学习曲线比较陡峭,需要花很多时间去理解。
有9位网友表示赞同!
CGI已经过时了吗?现在用其它技术开发网站更合适吧。
有18位网友表示赞同!
希望能找到一些关于 Python CGI 的入门教程,方便新手学习!
有16位网友表示赞同!
想用Python CGI创建一个简单的博客框架,请问怎么做呢?
有5位网友表示赞同!
Python CGI的安全性如何?需要注意哪些问题?
有5位网友表示赞同!
CGI编程可以实现很多有趣的功能,例如制作动态网站页面和交互式工具。
有19位网友表示赞同!