Mini-web中常用操作

1.接收浏览器的请求报文

self.request = socket_con.recv(4096).decode()

 if self.request:  # 如果收到

            # 将请求报文这整个字符串,截取成一行一行的字符串,存储到request_lines这个列表中

            request_lines = self.request.split("\r\n")
            # 获取请求报文中的请求行
            requeset_line = request_lines[0]   # ['GET /center.html HTTP/1.1', 'Host: 127.0.0.1:22222'.........]
            # 获取请求行中的请求资源路径
            self.res = re.match(r"\w+\s+(\S+)", requeset_line)  

            # 服务器处理浏览器发送过来的空请求

            self.path = self.res.group(1) # 取第一个分组,此时res='center.html'

            self.path = urllib.parse.unquote(self.path)  # 将路径解码,因为浏览器对中文进行了URL(%)编码

            self.path = os.getcwd() + self.path  

            # 拼接服务器完整路径   C:\Users\fenghua\Desktop\www3/index.html

2.之后进行静态查找    

def handle_static(self, path, socket_con):

         if not os.path.exists(path):  #  判断文件是否存在,注意语法

                return False
         else:

                if os.path.isfile(path):   # 判断路径是否是文件,是则读取,返回响应报文,不是则判断是否是文件夹

                else:

                    if not path.endswith("/"):  # 判断文件夹是否以/结尾,不是则返回指定路径
                        response_line = "HTTP/1.1 302 Found\r\n"
                        response_head = "Server: laozhao v3.0\r\n"
                        response_head += "Content-Type:text/html;charset=utf-8\r\n"
                        response_body = "您的路径被制定到" + path + "/"
                        response = response_line + response_head + "\r\n" + response_body
                        socket_con.send(response.encode())
                        socket_con.close()

                        return True

                    else:

                        #若是以/结尾,两种处理方式:

                        #1.进行路径拼接,path+index/path + default,进行响应报文返回

                        #2.自己重写html文件,返回响应报文

                        if os.path.exists(path + "index.html"):  # 判断文件存在
                              返回响应报文

                        elif os.path.exists(path + "default.html"):

                              返回响应报文

3.根据静态处理函数的返回值进行数据动态处理

def handle_sport(self, socket_con):   # 动态请求处理函数

self.request = socket_con.recv(4096).decode()
        if self.request:
            # 将请求报文这整个字符串,截取成一行一行的字符串,存储到request_lines这个列表中
            request_lines = self.request.split("\r\n")
            # 获取请求报文中的请求行
            requeset_line = request_lines[0]
            # 获取请求行中的请求资源路径
            self.res = re.match(r"\w+\s+(\S+)", requeset_line)
            # 服务器处理浏览器发送过来的空请求
        if self.res:
            self.path = self.res.group(1)
            self.path = urllib.parse.unquote(self.path)
            self.path = os.getcwd() + self.path
        # 服务器处理静态请求
        result = self.handle_static(self.path, socket_con)
        if result == False:
            # 以下不用判断是否以什么结尾了,都是动态请求
            # /Users/zhaojianyu/Desktop/WSIG/www3/index.py
            file_name = re.match(r'\S+www3/(\S+)', self.path).group(1)
            env = {
                        "PATH_INFO": file_name   # 文件名获取
                      }

            response_body = dynamic.mini_web_frame_2.application(env, self.start_response)

            #  此处调用application函数    获取响应体

           此函数定义在web应用程序中,在服务器调用,该函数实现web应用的函数调用,并返回相应的html文件内容或者自己定义的文字

           参数为1.文件名,注意必须以WISG协议规定格式,eg:env  进行传递

                     2.函数stat_response的引用,进行报文拼接

            response = self.response_header + "\r\n" + response_body
            socket_con.send(response.encode())
            socket_con.close()
            return

  #  WISG协议的对调函数start_response,在web应用中调用用于生成回复报文

参数1.状态码   200 OK

参数2.一个响应头列表,里边是一个元组

[("Content-type", "text/html;charset= utf-8")]

    def start_response(self, status, response_head):
        # 拼接响应行和响应头
        self.response_header = "HTTP/1.1 %s\r\n" % status  # HTTP/1.1 200 OK
        for k, v in response_head:

            self.response_header += "%s: %s\r\n" % (k, v)


4.web应用程序

主要用于处理动态请求,定义相应的处理函数,在application函数中进行调用

def application(environ, start_response):
    # 获取请求名
    file_name = environ["PATH_INFO"]

    try:

        #遍历定义好的字典,将传进来的动态请求(文件名)与字典中的文件名进行匹配

        for URL, FUNC in URL_DIRC.items():
            if re.match(URL, file_name):
                start_response("200 OK", [("Content-type", "text/html;charset= utf-8")])
                return FUNC(file_name)
    except Exception as e:
        start_response("404 error", [("Content-type", "text/html;charset= utf-8")])

        return '啥也没有,我的网站满足不了了你!!'

路由:在字典中添加元素----文件名:函数名

def route(filename):
    def outer(func):
        URL_DIRC[filename] = func
        def inner():
            return func()
        return inner

    return outer


几个处理函数

 @route()工厂函数的作用:将函数名传进去,再调用里边的装饰器outer

 outer作用:

        1、调用/执行outer函数
        2、将@outer下的函数的引用作为参数传递给outer
        3、将内函数的引用重新赋值给center等函数

@route('center.html')  # center = outer(center)

def center(file_name):

@route('index.html')

def index(file_name):

@route('add/\d+\.html')

def add(file_name):

@route('del/\d+\.html')

def delete(file_name):

@route(r"update/\w+\.html")

def update(file_name):

#/update/股票名/fdsfdsfsdfsdfds.html
@route("update/\w+/.*\.html")
def update_info(file_name):

以上几个处理函数就是对定义好的路由表进行字典内容的填充。此时字典内容为

{'center.html': <function center at 0x000001B0E14B7A60>, 'index.html': <function index at 0x000001B0E14B7B70>, 'add/\\d+\\.html': <function add at 0x000001B0E14B7C80>, 'del/\\d+\\.html': <function delete at 0x000001B0E14B7D90>, 'update/\\w+\\.html': <function update at 0x000001B0E14B7EA0>, 'update/\\w+/.*\\.html': <function update_info at 0x000001B0E14BA048>}

路由内部的装饰器

def outer(func):  #   center = outer(center)
        URL_DIRC[filename] = func
        def inner():
            return func()

        return inner


@route('center.html')  

def center(file_name):

   # 对html文件的操作

    with open("./templates/center.html", "rb") as f:

        content1 = f.read()

    #对数据库的操作

    con = connect(host='127.0.0.1', port=3306, user='root', password='123456',
                  database='选股系统', charset='utf8')
    cursors = con.cursor()
    sql = "select a.code,a.short,a.chg,a.turnover,a.price,a.highs,b.note_info from info as a inner join focus as b on a.id = b.info_id"
    cursors.execute(sql)  # 执行sql语句
    # str = "模拟:这是从mysql中查询到的数据"
    # {%content%}
    str1 = """
            <tr>
                   <td>%s</td>
                   <td>%s</td>
                   <td>%s</td>
                   <td>%s</td>
                   <td>%s</td>
                   <td>%s</td>
                   <td>%s</td>
                   <td>
                    <a type="button" class="btn btn-defalut btn-xs" href="/update/%s.html"><span class="glyphicon glyphicon
                    -star" aria="" -="" hidden="true"></span>修改</a>
                   </td>
                   <td>
                    <input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
                   </td>
            </tr>
    """
    html = ''
    for i in cursors.fetchall():  #  读取所有内容,遍历进行每行的内容显示
        html += str1 % (i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[1], i[0])  # 最后两个是更新的 股票名字,删除指定 股票代码


    content = re.sub(r"\{%content%\}", html, content1.decode()) 

    # re.sub()在content1.decode()中匹配\{%content%\},把\{%content%\}用html替代

    cursors.close()
    con.close()

    return content

用到的正则:

 1.code = re.match(r"update/(\w+)\.html", file_name).group(1)

    #将匹配的分组1的值赋值给code

 2.content = re.sub(r"\{%content%\}", html, content1.decode()) 

    # re.sub()在content1.decode()中匹配\{%content%\},把\{%content%\}用html替代,

\代表起始结束位置







猜你喜欢

转载自blog.csdn.net/weixin_31449201/article/details/80533245