创建Python网页服务器 - 布局与设置

2 投票
2 回答
2782 浏览
提问于 2025-04-17 05:52

我这样做对吗?我以前从来没有做过这样的事情,所以我不太确定自己在做什么。到目前为止,代码可以获取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

撰写回答