创建Python网页服务器 - 布局与设置
我这样做对吗?我以前从来没有做过这样的事情,所以我不太确定自己在做什么。到目前为止,代码可以获取html和css文件,这个没问题,但图片却加载不出来。我是不是需要为每种不同的文件类型都写一个新的“if”语句?还是我这样做有点傻呢……这是我写的代码:
import string,cgi,time
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import os
import mimetypes
#import pri
port = 888
host = "0.0.0.0"
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
try:
#RequestedURL = self.path
mimeType = mimetypes.guess_type(self.path)[0]
fileType = mimetypes.guess_extension(mimeType)
infoList = [mimeType, fileType]
if infoList[1] != ".py":
self.send_response(200)
self.send_header('Content-type', mimeType)
self.end_headers()
f = open(curdir + sep + self.path, "rb")
self.wfile.write(f.read())
f.close()
return
if fileType == ".py":
pythonFilename = self.path.lstrip("/")
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
pyname = pythonFilename.replace("/", ".")[:-3]
print pythonFilename
print pyname
temp1 = pyname.split(".")
temp2 = temp1[-1]
print temp2
module = __import__(root.index)
self.wfile.write(module.root.index.do_work())
#module = __import__("test.index")
#self.wfile.write( module.index.do_work())
return
return
except IOError:
self.send_error(404,'File Not Found: %s' % self.path)
def do_POST(self):
global rootnode
try:
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
query=cgi.parse_multipart(self.rfile, pdict)
self.send_response(301)
self.end_headers()
upfilecontent = query.get('upfile')
print "filecontent", upfilecontent[0]
self.wfile.write("<HTML>POST OK.<BR><BR>");
self.wfile.write(upfilecontent[0]);
except :
pass
def main():
try:
server = HTTPServer((host, port), MyHandler)
print 'started httpserver:'
print ("Host: " + (host))
print ("Port: " + str(port))
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
server.socket.close()
if __name__ == '__main__':
main()
html和css可以正常工作,但png图片加载不出来
2 个回答
1
关于一堆 if
语句,通常的做法是准备一个文件,用来处理文件扩展名和 MIME 类型之间的对应关系(可以参考这里:地球上所有 MIME 类型与文件扩展名的列表)。把这些信息读入一个合适的数据结构中。
你应该尽量把所有文件都当作二进制文件来打开,除非它们是文本类型的 MIME;对于文本类型的文件,你需要确保行结束符符合相关的标准(RFC),不过这些标准我已经很多年没用过了,因为我没有写过需要上线的网络服务器)。
还有一个语法上的小提示:
>>> ('foo')
'foo'
>>> ('foo',)
('foo',)
>>>
你的括号是多余的。你可以直接根据你提取的值进行索引。
4
你做得不错,不过你的条件判断有点多余。我建议你可以把代码改得更简洁,使用一个循环和字典来检查类型:
mime = {"html":"text/html", "css":"text/css", "png":"image/png"}
if RequestedFileType in mime.keys():
self.send_response(200)
self.send_header('Content-type', mime[RequestedFileType])
self.end_headers()
print RequestedFileType
f = open(curdir + sep + self.path)
self.wfile.write(f.read())
f.close()
return
另外,你现在是把二进制文件当作文本来发送。你应该用 open(curdir + sep + self.path, "b") 这样的方式来打开文件,而不是 open(curdir + sep + self.path)。
来自toptal.com的Gergely