1. http协议
请求的格式(request ---浏览器向服务器发送的消息)
请求方式: URL HTTP/1.1
K1:V1
K2:V2
请求正文/请求体(get请求没有请求数据)
响应的格式(response ---服务端回复给浏览器的消息)
HTTP/1.1 200 OK # response headers 响应头
HTTP/1.1 状态码 状态描述
K1:V1
K2:V2
响应数据(响应体) -HTML
状态码:
1XX
2XX 200
3XX 301 302 重定向
4xx 请求的问题
5xx 服务器的问题
url
http://www.cnblogs.com/majj?k1=v1&k2=v2
8种请求方式:
GET
POST
HEAD
PUT
DELETE
TRACE
OPTIONS
CONNECT
发请求到接收响应的流程: 1. 在浏览器的地址栏中输入url,回车. 发送一个遵循HTTP协议的GET请求. 2. 服务器接收到请求,获取到路径.根据路径执行对应的函数,获取想要的内容. 3. 读取到一个HTML的文本,替换文本中的内容,生成一个新的HTML文本. 4. 回复一个遵循HTTP协议的响应. 5. 浏览器接收到响应,拿响应中的响应体,进行渲染.
import socket # 创建socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen() while True: # 等待连接 conn, addr = sk.accept() # 接收数据 data = conn.recv(8096) print(data) # 返回状态行 conn.send(b'HTTP/1.1 200 OK ') # 返回数据 conn.send(b'<h1>ok</h1>') # 关闭连接 conn.close()
浏览器端 输入地址 127.0.0.1:8000
2. web 框架(socket服务端)
功能:
a. socket 收发消息
b. 根据不同的路径返回不同的内容
c. 可以返回动态页面(字符串替换 -模板的渲染) jinja2
分类:
Django 实现b,c功能
flask 实现b功能
tornado 实现a,b,c功能
另类分类:
Django 大,重量级
其他 轻量级
import socket # 创建socket对象 server = socket.socket() # 绑定IP和端口 server.bind(('127.0.0.1', 8000)) # 监听 server.listen() while 1: # 等待连接 conn, addr = server.accept() # 接收数据 data = conn.recv(1024) data = data.decode('utf-8') # print(data) url = data.split()[1] print(url) # 返回状态行 conn.send(b'HTTP/1.1 200 OK ') if url == '/oumei': conn.send(b'<h1>oumei</h1>') elif url == '/rihan': conn.send(b'<h1>rihan</h1>') else: conn.send(b'<h1>404 not found</h1>') # 关闭连接 conn.close()
import socket server = socket.socket() server.bind(('127.0.0.1', 8000)) server.listen() def oumei(url): ret = 'oumei -{}'.format(url) return ret.encode('utf-8') def rihan(url): ret = 'rihan -{}'.format(url) return ret.encode('utf-8') while 1: conn, addr = server.accept() data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] print(url) conn.send(b'HTTP/1.1 200 OK ') if url == '/oumei': ret = oumei(url) elif url == '/rihan': ret = rihan(url) else: ret = b'404 not found' conn.send(ret) conn.close()
import socket server = socket.socket() server.bind(('127.0.0.1', 8000)) server.listen() def oumei(url): ret = 'oumei -{}'.format(url) return ret.encode('utf-8') def rihan(url): ret = 'rihan//// - {}'.format(url) return ret.encode('utf-8') def guochan(url): ret = 'guochan - {}'.format(url) return ret.encode('utf-8') list = [ ('/oumei', oumei), ('/rihan', rihan), ('/guochan', guochan) ] while 1: conn, addr = server.accept() data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] print(url) conn.send(b'HTTP/1.1 200 OK ') func = None for el in list: if el[0] == url: func = el[1] break if func: ret = func(url) else: ret = b'404 not found' conn.send(ret) conn.close()
import socket server = socket.socket() server.bind(('127.0.0.1', 8000)) server.listen() def oumei(url): ret = 'oumei - {}'.format(url) return ret.encode('utf-8') def rihan(url): ret = 'rihan//// - {}'.format(url) return ret.encode('utf-8') def guochan(url): ret = 'guochan - {}'.format(url) return ret.encode('utf-8') def index(url): with open('index.html', 'rb') as f: ret = f.read() return ret list = [ ('/oumei', oumei), ('/rihan', rihan), ('/guochan', guochan), ('/index', index), ] while True: # 等待连接 conn, addr = server.accept() # 接收数据 data = conn.recv(8096) data = data.decode('utf-8') url = data.split()[1] print(url) # 返回状态行 conn.send(b'HTTP/1.1 200 OK ') func = None for i in list: if i[0] == url: func = i[1] break if func: ret = func(url) else: ret = b'404 not found' conn.send(ret) # 关闭连接 conn.close()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> div{ width: 200px; height: 200px; line-height: 200px; text-align: center; background-color: greenyellow; margin: 0 auto; } </style> </head> <body> <div><b>这里是index</b></div> </body> </html>
import time import socket server = socket.socket() server.bind(('0.0.0.0', 8000)) server.listen() def oumei(url): ret = 'oumei - {}'.format(url) return ret.encode('utf-8') def rihan(url): ret = 'rihan//// - {}'.format(url) return ret.encode('utf-8') def guochan(url): ret = 'guochan - {}'.format(url) return ret.encode('utf-8') def index(url): with open('index.html', 'rb') as f: ret = f.read() return ret def timer(url): now = time.strftime('%Y-%m-%d %H:%M:%S') with open('time.html', 'r', encoding='utf-8') as f: data = f.read() data = data.replace('@@time@@', now) return data.encode('utf-8') lst = [ ('/oumei', oumei), ('/rihan', rihan), ('/guochan', guochan), ('/index', index), ('/time', timer), ] while 1: conn,addr = server.accept() data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] print(url) conn.send(b'HTTP/1.1 200 OK ') func = None for i in lst: if i[0] == url: func = i[1] break if func: ret = func(url) else: ret = b'404 not found' conn.send(ret) # 关闭连接 conn.close()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>当前时间是: @@time@@ </h1> </body> </html>
""" 根据URL中不同的路径返回不同的内容--函数进阶版 返回HTML页面 让网页动态起来 wsgiref模块版 """ from wsgiref.simple_server import make_server # 将返回不同的内容部分封装成函数 def index(url): # 读取index.html页面的内容 with open("index.html", "r", encoding="utf8") as f: s = f.read() # 返回字节数据 return bytes(s, encoding="utf8") def home(url): with open("home.html", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8") def timer(url): import time with open("time.html", "r", encoding="utf8") as f: s = f.read() s = s.replace('@@time@@', time.strftime("%Y-%m-%d %H:%M:%S")) return bytes(s, encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/", index), ("/home/", home), ("/time/", timer), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" return [response, ] if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
from wsgiref.simple_server import make_server from jinja2 import Template def index(url): # 读取HTML文件内容 with open("index2.html", "r", encoding="utf8") as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({'name': 'wusir', 'hobby_list': ['马杀鸡', '喝酒', '烫头', '蹦迪']}) # 把数据填充到模板中 return bytes(ret, encoding="utf8") def home(url): with open("home.html", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/", index), ("/home/", home), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" return [response, ] if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <h1>姓名:{{name}} </h1> <h1>爱好:</h1> <ul> {% for hobby in hobby_list %} <li>{{hobby}}</li> {% endfor %} </ul> </body> </html>
3. Django
1. 下载
1. 命令行
pip install django==1.11.16
按住shift 右击文件夹
2. 创建项目
django-admin startproject 项目名
3. 启动项目
cd 切换到项目目录下 manage.py
pyhton .manage.py runserver
# 默认端口号127.0.0.1:8000
pyhton .manage.py runserver 80 把端口号改成80
pyhton .manage.py runserver 0.0.0.0:80 把IP改成0.0.0.0,端口号改成80
2. pycharm 启动项目
4. 配置:
TEMPLATES
'DIRS': [os.path.join(BASE_DIR, 'templates'] # HTML文件要存放的地方
DATABASES 数据库, 可以配多个数据库
静态文件的配置
STATIC_URL = '/static/' # 别名
# 自己配置, 列表里写静态文件的路径, 可以配置多个路径
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
什么是静态文件?
# Static files (CSS, JavaScript, Images) 等不常发生变化的文件