首页 > Web开发 > 详细

web应用+250斗笔式模拟框架

时间:2019-07-26 22:44:49      阅读:81      评论:0      收藏:0      [点我收藏+]

http协议简介

  HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传送协议。

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。

http协议特性

(1) 基于TCP/IP

  http协议是基于TCP/IP协议之上的应用层协议

(2) 基于请求-响应模式

  HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并 返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应

(3) 无状态保存

   HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议 自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个 级别,协议对于发送过的请求或响应都不做持久化处理。你连接我一次,我响应一次就断开了

(4)无连接

无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

请求协议格式:

大前提:字符串/字节

请求首行  请求方式  url   (路径?get请求参数)   协议/版本号

请求头  key:value

请求体  数据(只有post请求才会有请求体)

换行:\r\n     请求头与请求体之间用\r\n\r\n

技术分享图片

 响应协议格式:

响应首行   协议/版本号  状态码  状态码译文

响应头  Content-Type:text/html  key:value

响应体  <h1>hello</h>  这才是客服端浏览器上显示的东西

换行:\r\n     响应头与响应体之间用\r\n\r\n

web框架本质

  大家应该都晓得,所有web应用,本质上就是一个socket服务端,用户浏览器就是一个socket客服端

  下面简单的模拟socket举个例子

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import socket
 5 
 6 
 7 def handle_request(client):
 8     data = client.recv(8096)
 9     print(data.decode(utf8))
10     client.send("HTTP/1.1 200 OK\r\n\r\n".encode(utf8))
11     client.send("Hello WeiSuoJun".encode(utf8))
12 
13 
14 def main():
15     sock = socket.socket()
16     sock.bind((localhost, 9999))
17     sock.listen(5)
18 
19     while True:
20         conn, addr = sock.accept()
21         handle_request(conn)
22         conn.close()
23 
24 
25 if __name__ == __main__:
26     main()

  后边为了方便的开发,大堆的web框架出来了,但是各种框架开发模式应该有所不同,不管咋样最终要开发出的应用程序都要和服务器配合,才能够给用户提供服务,这样服务器程序就要为不同的框架提供不同的支持,这就意味着一片混乱来了,咋能克服混乱局面,大家商量好这套标准。WSGI就诞生了、一套套规范,定义了一些web app与web server之间接口的格式,主要就是实现两者之间的解耦,Python中标准库提供的独立WSGI服务器叫wsgiref这个模块,本质就是socket服务端。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from wsgiref.simple_server import make_server
 5 
 6 def RunServer(environ, start_response):
 7     print(environ)
 8     start_response(200 OK, [(Content-Type, text/html)])
 9     return [bytes(<h1>Hello, WeiSuoJun!</h1>, encoding=utf-8), ]
10 
11 
12 if __name__ == __main__:
13     httpd = make_server(127.0.0.1, 9999, RunServer)
14     print("Serving HTTP on port 9999...")
15     httpd.serve_forever()

 

environ请求所有相关信息

技术分享图片

基于socket模拟web框架的斗笔行为(web250框架)

  (静态页面)实现的思想:等待用户进来连接,收到请求的数据,对数据(字节转字符串)进行分割,拿到请求url走对应的函数(若没有函数进行匹配就返回404),(暂且还没的视图这么一说),在对应的函数(暂且还没得视图这么一说)里边做打开文件操作,然后返回给用户。
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import socket
 5 
 6 
 7 def f1(request):
 8     f = open(index.html, rb)
 9     data = f.read()
10     f.close()
11     return data
12 
13 
14 def f2(request):
15     f = open(article.html, rb)
16     data = f.read()
17     f.close()
18     return data
19 
20 
21 routers = [
22     (/xxxx, f1),
23     (/oooo, f2),
24 ]
25 
26 
27 def run():
28     sock = socket.socket()
29     sock.bind(("127.0.0.1", 8080))
30     sock.listen(5)
31 
32     while True:
33         conn, addr = sock.accept()
34         data = conn.recv(8096)
35         data = str(data, encoding=utf8)
36         headers, bodys = data.split(\r\n\r\n)
37         temp_list = headers.split(\r\n)
38         method, url, protocal = temp_list[0].split( )
39         conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
40 
41         func_name = None
42         for item in routers:
43             if item[0] == url:
44                 func_name = item[1]
45                 break
46         if func_name:
47             response = func_name(data)
48         else:
49             response = b"404"
50 
51         conn.send(response)
52 
53         conn.close()
54 
55 
56 if __name__ == __main__:
57     run()
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <h1>用户登录</h1>
 9 <form action="">
10     <p><input type="text" placeholder="用户名"></p>
11     <p><input type="text" placeholder="密码"></p>
12     <p><input type="submit" value="提交"></p>
13 </form>
14 </body>
15 </html>
index.html
技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <table border="1">
 9         <thead>
10             <tr>
11                 <th>id</th>
12                 <th>用户名</th>
13                 <th>邮箱</th>
14             </tr>
15         </thead>
16         <tbody>
17             <tr>
18                 <th>1</th>
19                 <th>@root@</th>
20                 <th>root@qq.com</th>
21             </tr>
22         </tbody>
23     </table>
24 </body>
25 </html>
article.html

 

   (动态页面)实现思想:只是在静态的基础上,通过pymysql模块连接数据库,拿到数据然后使用jinja2对模板的渲染,然后返回给用户。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import socket
 5 
 6 
 7 def f1(request):
 8     f = open(index.html, rb)
 9     data = f.read()
10     f.close()
11     return data
12 
13 
14 def f2(request):
15     f = open(article.html, r, encoding=utf8)
16     data = f.read()
17     f.close()
18     import time
19     ctime = time.ctime()
20     data = data.replace(@root@, str(ctime))
21     return data.encode(utf8)
22 
23 
24 def f3(request):
25     import pymysql
26     conn = pymysql.connect(host=127.0.0.1, port=3306, user=root, passwd=‘‘, db=db2)
27     cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
28     cursor.execute("select id,name,extra from users")
29     user_list = cursor.fetchall()
30     cursor.close()
31     conn.close()
32     print(user_list)
33 
34     f = open(userinfo.html, r, encoding=utf8)
35     data = f.read()
36     f.close()
37 
38     # 专门来渲染模板
39     from jinja2 import Template
40     template = Template(data)
41     data = template.render(user_list=user_list, name=搞大佬)
42     print(data)
43     return data.encode(utf8)
44 
45 
46 routers = [
47     (/xxxx, f1),
48     (/oooo, f2),
49     (/yyyy, f3),
50 ]
51 
52 
53 def run():
54     sock = socket.socket()
55     sock.bind(("127.0.0.1", 13333))
56     sock.listen(5)
57 
58     while True:
59         conn, addr = sock.accept()
60         data = conn.recv(4096)
61         data = str(data, encoding=utf8)
62         headers, bodys = data.split(\r\n\r\n)
63         temp_list = headers.split(\r\n)
64         method, url, protocal = temp_list[0].split( )
65         conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
66 
67         func_name = None
68         for item in routers:
69             if item[0] == url:
70                 func_name = item[1]
71                 break
72         if func_name:
73             response = func_name(data)
74         else:
75             response = b"404"
76 
77         conn.send(response)
78 
79         conn.close()
80 
81 
82 if __name__ == __main__:
83     run()

 

index.html与article.html与上边相同

技术分享图片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <table border="1">
 9         <thead>
10             <tr>
11                 <th>id</th>
12                 <th>用户名</th>
13                 <th>描述</th>
14             </tr>
15         </thead>
16         <tbody>
17             {% for row in user_list %}
18                 <tr>
19                     <td>{{ row.id }}</td>
20                     <td>{{ row.name }}</td>
21                     <td>{{ row.extra }}</td>
22                 </tr>
23             {% endfor %}
24         </tbody>
25         {{ name }}
26     </table>
27 </body>
28 </html>
userinfo.html

 

 实现的效果如图:

技术分享图片技术分享图片技术分享图片   

 总结:

  1.http 无状态 短连接

  2.浏览器(socket客服端)

     网站(socket服务端)

  3.自己搞网站

    a.socket服务端

    b.根据url不同返回不同的内容

      路由系统: url---->函数(视图函数)

    c.字符串返回给用户

      模板引擎渲染:html充当模板(特殊字符)

             当然自己可以任意数据

             字符串

  4.web框架

    a,b,c                    ------------------------------->Tornado

    [第三方a],b,c        ------------------------------->wsgiref ---->Django

    [第三方a],b,[第三方c]---------------------------->warkzeug--->Flask

                

 

web应用+250斗笔式模拟框架

原文:https://www.cnblogs.com/Alexephor/p/11240100.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!