http服务器究竟做了什么(三)

本节内容将通过一些示例来说明CGI程序.前面讲过CGI程序可以用任何语言编写,考虑到便捷性,这里用python来展示CGI程序.

首先搭建服务器.我这里用了最轻量级的http服务器tinyhttp,总共代码只有500行左右,后面的服务器代码分析也是基于这个.在他的htdocs里添加一个test.cgi,写CGI代码.注意,test.cgi脚本要有可执行的的权限,否则访问test.cgi时,将直接读取里面的文本,而不是执行该文件. test.cgi代码如下:

#!/usr/bin/python        #注意要添加这行,表示该文件会被python解析器解析
# -*- coding: UTF-8 -*-
print "Content-type:text/html"
print                               # 空行,告诉服务器结束头部
print '<html>'
print '<head>'
print '<meta charset="utf-8">'
print '<title>Hello World - 我的第一个 CGI 程序!</title>'
print '</head>'
print '<body>'
print '<h2>Hello World! 我是第一个CGI程序</h2>'
print '</body>'
print '</html>'

开启我们的服务器,访问/test.cgi,浏览器会得到:

Hello World! 我是第一个CGI程序

我做实验时,第一次没有显示,报错信息/usr/bin/python^M: bad interpreter: No such file or directory. 是因为cgi文本格式为dos,用vim set ff=unix就可以改过来了.

我们再来梳理一下浏览器得到这个结果的过程:

浏览器发起请求,服务器收到请求,转给CGI程序处理.CGI打印一段简单的http文本,重定向给服务器,服务器返回给浏览器,然后我们就看到了结果.

打印环境变量:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os

print "Content-type:text/html"
print                               # 空行,告诉服务器结束头部
print '<html>'
print '<meta charset=\"utf-8\">'
print '<b>环境变量</b><br>'
print '<ul>'

list_env = ['REQUEST_METHOD', 'QUERY_STRING', 'CONTENT_LENGTH', 'CONTENT_TYPE','CONTENT_FILE','PATH_INFO','PATH_TRANSLATED','SCRIPT_NAME']

for key in os.environ.keys():
	if key in list_env:
		print "<li><span style='color:green'>%30s </span> : %s </li>" % (key, os.environ[key])
为了保持简单,程序中只输出相关的环境变量.

请求 /test.cgi?name=shonm&age=25 得到的结果为:


我们再来看post的结果,html的页面代码为:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试post</title>
</head>
<body>
<form action="/test.cgi" method="post">
	姓名: <input type="text" name="name">  <br />

	年龄: <input type="text" name="age" />
	<input type="submit" value="提交" />
</form>
</body>
</html>

/test.cgi:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os,cgi

print "Content-type:text/html"
print                               # 空行,告诉服务器结束头部
print '<html>'
print '<meta charset=\"utf-8\">'
print '<b>环境变量</b><br>'
print '<ul>'

list_env = ['REQUEST_METHOD', 'QUERY_STRING', 'CONTENT_LENGTH', 
			'CONTENT_TYPE','CONTENT_FILE','PATH_INFO','PATH_TRANSLATED','SCRIPT_NAME']

for key in os.environ.keys():
	if key in list_env:
		print "<li><span style='color:green'>%30s </span> : %s </li>" % (key, os.environ[key])

if os.environ['REQUEST_METHOD'] == 'POST':
	# 创建 FieldStorage 的实例化
	form = cgi.FieldStorage() 

	# 获取数据
	name = form.getvalue('name')
	age  = form.getvalue('age')
	print '<br> name is %s, age is %s ' %(name, age)

点击提交,得到:


POST请求,在环境变量中没有关于请求内容的字段,只有内容的长度,根据这个长度,然后服务器再次读取socket获取内容.上面的内容为:'name=shonm&age=25',和用GET请求(可以改form method = 'get')时QUERY_STRING字段的内容一致.








展开阅读全文

没有更多推荐了,返回首页