BaseHTTPRequestHandler实现简单的接口

本文介绍了如何在Python中使用BaseHTTPRequestHandler实现简单的HTTP接口,包括处理POST请求、文件上传和下载。通过BaseHTTPServer模块,可以创建一个HTTP服务器,处理GET、POST等请求。文章提到了环境配置,如PyCharm连接远程Linux解释器,并给出了相关代码示例和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BaseHTTPRequestHandler实现简单的接口

只想写一些简单的接口,结果踩了好多坑,在此记录一下(含客户端数据上传/下载)

一、环境
  1. 先介绍一下我用的集成环境吧,之前一直用Eclipse,页面显示相当舒服,语法查错补全也特别给力,但是有一些缺点,比如只能安装在window环境下,要想安装在linux环境下需要该环境有图形页面(是的,我为了用它生生把一个mini版的系统给多安装了个图形页面),再比如tab空格移植到linux环境下后不是标准的4空格,这样就会导致你Eclipse编辑的文件在linux下修改格式会让人很抓狂,当然这个我没经历过,是改我项目的小哥哥告诉我的,他改空格改到眼睛发红,哈哈哈…
    基于以上两点,本次集成环境用的是Pycharm,界面太丑!Pycharm连的远程linux上的python解释器,然后把本地代码实时同步到linux环境上,这样就能避免两套环境不一致导致同一个脚本出现不同的错误。

Pycharm连远程解释器链接:https://blog.youkuaiyun.com/five3/article/details/78615589

  1. Linux:centos6.5
  2. python:python2.6
二、代码功能介绍
1.BaseHTTPRequestHandler介绍

这是一个以TCPServer为基础开发的模块,可以在请求外层添加http协议报文,发送http协议。

基于BaseHTTPServer 的Http Server的处理流程:

1.HTTPServer绑定对应的应答类(BaseHTTPRequestHandler )
http_server = HTTPServer((’’, int(port)), ServerHTTP)
2.监听端口:
http_server.serve_forever()
serve_forever()方法使用select.select()循环监听请求,当接收到请求后调用
当监听到请求时,取出请求对象
3.应答:
创建新线程以连接对象(开始理解成请求对象)为参数实例化应答类:ServerHTTP()
应答类根据请求方式调用ServerHTTP.do_XXX处理方法

常用方法/属性:

BaseHTTPRequestHandler.path   #包含的请求路径和GET请求的数据
BaseHTTPRequestHandler.command  #请求类型GET、POST…
BaseHTTPRequestHandler.request_version   #请求的协议类型HTTP/1.0、HTTP/1.1
BaseHTTPRequestHandler.headers   #请求的头
BaseHTTPRequestHandler.responses   #HTTP错误代码及对应错误信息的字典
BaseHTTPRequestHandler.handle()   #用于处理某一连接对象的请求,调用handle_one_request方法处理
BaseHTTPRequestHandler.handle_one_request()  #根据请求类型调用do_XXX()方法,XXX为请求类型
BaseHTTPRequestHandler.do_XXX()   #处理请求
BaseHTTPRequestHandler.send_error()  #发送并记录一个完整的错误回复到客户端,内部调用send_response()方法实现
BaseHTTPRequestHandler.send_response()   #发送一个响应头并记录已接收的请求
BaseHTTPRequestHandler.send_header()   #发送一个指定的HTTP头到输出流。 keyword 应该指定头关键字,value 指定它的值
BaseHTTPRequestHandler.end_headers()   #发送一个空白行,标识发送HTTP头部结束
BaseHTTPRequestHandler.wfile   #self.connection.makefile(‘rb’, self.wbufsize) self.wbufsize = -1 应答的HTTP文本流对象,可写入应答信息
BaseHTTPRequestHandler.rfile  #self.connection.makefile(‘wb’, self.rbufsize) self.rbufsize = 0 请求的HTTP文本流对象,可读取请求信息

参考:https://blog.youkuaiyun.com/xhw88398569/article/details/49179967

2. 简单的post请求,代码如下:
def do_POST(self)
	enc = "UTF-8"              #设置返回的编码格式
    path = str(self.path)     #获取请求的url
	length = int(self.headers.getheader('content-length'))  #获取除头部后的请求参数的长度
    datas = urlparse.parse_qs(self.rfile.read(length), keep_blank_values=1)  #获取请求参数数据,请求数据为json字符串
    if path=="/scandatas":   
            models = datas["models"][0]    #获取models参数数据
      		pass(可以添加对参数的逻辑处理)

			#以下是返回报文
            self.send_response(200)        #返回状态码
            self.send_header("Content-type", "text/html;charset=%s" % enc) #返回响应头内容
            self.end_headers()              #返回响应头结束
            buf = {"status": 0,                 #返回包体数据
                   "data": {
                       "filepath": "上传答题卡成功"}}
            self.wfile.write(json.dumps(buf))  #发送json格式的返回包体

如果返回html,buf如下

buf = '''<!DOCTYPE HTML>
                <html>
                    <head><title>Post page</title></head>
                    <body>Post Data:%s  <br />Path:%s</body>
                </html>'''%(datas,self.path)
3. 文件下载,代码如下(含get请求):
def do_POST(self):
	path=self.path
	if path=="/download":
        models=datas["models"][0]
        self.send_response(200)
        self.send_header("Content-type","text/html;charset=%s" % enc)
        self.end_headers()
        buf ={"status": 0,
              "data":{
                  "filepath": "http://capi.syaccuracytest.com/download/zip/"+models+".zip?"+models}}   #返回文件下载地址(点击下载地址是个get请求)
        self.wfile.write(json.dumps(buf))
def do_GET(self):
        paths = self.path
        query = urllib.splitquery(paths)
        datas = query[1]
        models = datas
        path=str(query[0])
        enc = "UTF-8"
        if path[:13]=="/download/zip":        #判断下载路径
                fn = os.path.join(INPUTF_PATH, models+".zip")          #下载文件地址
                try:
                    resultf = open(fn, 'rb')                                          #以读的形式打开下载文件
                except BaseException:
                    self.send_response(200)                                    #请求下载的文件不存在返回文件不存在报文
                    self.send_header("Content-type", "text/html;charset=%s" % enc)
                    self.end_headers()
                    print "不存在"
                    buf = "获取扫描数据失败,请重新获取数据"
                else:
                    self.send_response(200)                           #文件存在返回状态码
                    self.send_header("Content-type", "application/octet-stream")  #返回请求格式为"application/octet-stream"
                    self.end_headers()  
                    buf = resultf.read()           #读取文件发送给客户端
                self.wfile.write(buf)
4. 文件上传
代码如下
    def do_POST(self):
        enc = "UTF-8"
        path = str(self.path)
        if path=="/upload":
            form = cgi.FieldStorage(
                fp=self.rfile,
                headers=self.headers,
                environ={'REQUEST_METHOD': 'post',
                         'CONTENT_TYPE': self.headers['Content-Type']
                         }
            )
            models=form['models'].value       #获取models参数值
            datas=form['file'].value                #获取上传文件内容
            fname=models+".zip"
            fn = os.path.join(INPUTF_PATH, fname)   #生成文件存储路径
            outf = open(fn, 'wb')                        #写打开文件
            outf.write(datas)                  #将接收到的内容写入文件
            outf.close()             #关闭文件
            self.send_response(200)       
            self.send_header("Content-type", "text/html;charset=%s" % enc)
            self.send_header("test", "This is test!")
            self.end_headers()
            buf = {"status": 0,
                  "data":{
                      "msg": u"上传成功"}}
            self.wfile.write(json.dumps(buf))
cgi.FieldStorage用法

参考:https://blog.youkuaiyun.com/langqing12345/article/details/46539545
注:使用cgi.FieldStorage前,一定不要对data做任何处理,我也不知道为什么,反正调试不过,知道原因后会再更上来的

最后提示各位,如果你只是想自己写个接口玩玩,可以用BaseHTTPRequestHandler来尝试,否则一定不要用它,特别难写且好多坑,也没有很多参考文档。

当然,如果你是python大佬,随您用哎喂!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值