1.所有的WEB框架或WEB请求本质上是什么?
答:所有的WEB框架或WEB请求本质上是一个socket。
2.http是什么呢?
答:服务端无论通过Apache还是nginx实现,只要服务端运行,本质上就是一个socket服务端;
浏览器充当的是socket客户端,浏览器去服务器端请求,建立一次TCP链接。连接完成之后,一次请求,一次响应。咔-断开了!
断开了之后,客户端再次发送请求给服务器端,服务器端这时是不知道客户端是谁的。
所以说,http是无状态的。
3.自己写一个服务端:所有的web框架的本质就是这15行代码。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:Zoe 4 import socket 5 def handle_request(client): 6 buf = client.recv(1024) 7 client.send("HTTP/1.1 200 OK ".encode("utf-8")) 8 client.send("Hello, Seven".encode("utf-8")) 9 def main(): 10 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 11 sock.bind(('localhost', 800)) 12 sock.listen(5) 13 while True: 14 connection, address = sock.accept() 15 handle_request(connection) 16 connection.close() 17 if __name__ == '__main__': 18 main()
在浏览器界面输入:localhost:800或127.0.0.1:800,浏览器界面返回“Hello, Seven”。
在这个服务器端,绑定ip是自己写的。
4.在Python中,python标准库提供的独立WSGI服务器称为wsgiref。wsgiref模块帮我们封装好了socket,只要定义函数调用模块内部已经封装好了的socket。
注:WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:Zoe 4 from wsgiref.simple_server import make_server 5 def RunServer(environ, start_response): 6 #environ封装了所有从客户端发来的数据; 7 #start_response封装要返回给用户的数据,比方说:响应头,状态码等 8 start_response('200 OK', [('Content-Type', 'text/html')]) 9 return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ] #返回的内容 10 if __name__ == '__main__': 11 httpd = make_server('', 8000, RunServer) #首先创建一个socket服务端,当有客户端连接进来,会触发RunServer方法。 12 print("Serving HTTP on port 8000...") 13 httpd.serve_forever()
5.实际网页访问过程中,通过在url中传入的不同的参数返回不同的结果。那么,怎么获取用户在url中传入的值呢?
如:http://www.cnblogs.com/zoe233中传入了zoe233.
实例:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:Zoe 4 from wsgiref.simple_server import make_server 5 6 def handle_index(): 7 return [b'<h1>Hello,index</h1>',] 8 9 def handle_data(): 10 return ['<h1>Hello,data!</h1>'.encode('utf-8'),] 11 12 URL_DICT={ 13 '/index':handle_index, 14 '/data':handle_data, 15 } 16 def RunServer(environ, start_response): 17 start_response('200 OK', [('Content-Type', 'text/html')]) 18 current_url=environ['PATH_INFO'] 19 func=None 20 if current_url in URL_DICT: 21 func=URL_DICT[current_url] 22 if func: 23 return func() 24 else: 25 return [b'<h1>404</h1>',] 26 27 # return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ] 28 if __name__ == '__main__': 29 httpd = make_server('', 8000, RunServer) 30 print("Serving HTTP on port 8000...") 31 httpd.serve_forever()
运行上述实例,在浏览器界面输入127.0.0.1:800/data,返回“Hello,data!”;
在浏览器界面输入127.0.0.1:800/index,返回“Hello,index”;
在浏览器界面输入127.0.0.1:800/2333,返回“404”;
在上面的实例中,我们通过debug查看所有从客户端发来的信息中,字段PATH_INFO存储了url后面的参数值。通过environ['PATH_INFO']获取参数值,再通过字典映射函数,通过if判断让服务端相应相对应的反馈。
6.在实际网页中,有诸如下一页,第一页等传入信息为#p1,#p2的url参数的传入是如何实现的呢?
因为用上面的方法,会产生大量的重复的无用函数。
我们可以用正则表达式来作为匹配对象,将同类的参数归为一类。
如http://www.cnblogs.com/zoe233/default.html?page=3中将参数“/zoe233/default.html?page=3”写成“*page=d$”
7.上面的实例中,返回的值是我们自己写的,可以返回文件吗?
可以。
实例:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:Zoe 4 from wsgiref.simple_server import make_server 5 6 def handle_index(): 7 f=open("index.html",mode='rb') 8 data=f.read() 9 f.close() 10 return [data,] 11 12 def handle_data(): 13 return ['<h1>Hello,data!</h1>'.encode('utf-8'),] 14 15 URL_DICT={ 16 '/index':handle_index, 17 '/data':handle_data, 18 } 19 def RunServer(environ, start_response): 20 start_response('200 OK', [('Content-Type', 'text/html')]) 21 current_url=environ['PATH_INFO'] 22 func=None 23 if current_url in URL_DICT: 24 func=URL_DICT[current_url] 25 if func: 26 return func() 27 else: 28 return [b'<h1>404</h1>',] 29 30 # return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ] 31 if __name__ == '__main__': 32 httpd = make_server('', 8000, RunServer) 33 print("Serving HTTP on port 8000...") 34 httpd.serve_forever()
8.如果页面特别多,我们可以将所有的html文件放在一个文件夹内,以后要打开文件只要加上文件的路径即可。如View。
如果函数特别多,我们可以将所有的函数都在一个文件夹内。如Controller。调用函数时只要import Controller模块即可。
数据库文件都放在Model.
这种写法分为好几中WEB框架的写法:
MVC
Model View Controller
数据库 模板文件 业务处理
MTV
Model Template View
数据库 模板文件 业务处理
WEB框架:MVC、MTV
MVC、MTV的区别在于文件目录名称的区别。