DNS工作流程
什么是DNS:
是DNS解析系统,记录着 域名以及IP的对应关系
比如要访问www.163.com,它经历的过程:
先看本地DNS服务器缓存有没有,没有去DNS根服务器(全球13台),
DNS根服务器管理着.com、.net...这类服务器,然后它将.com顶级DNS服务器的ip地址返回给本地DNS服务器
然后本地DNS服务器带着ip地址去找顶级DNS服务器,而顶级DNS服务器管理者163.com、123.com..这类DNS权威服务器,然后它将163.comDNS权威服务器的ip地址返回
最后本地DNS服务器在带着IP地址去找DNS权威服务器,DNS权威服务器下管理着www.163.com这类的二级域名的DNS服务器,然后将找到的ip地址返回给本地DNS服务器,本地DNS服务器写入缓存
HTTP协议介绍
请求头:
GET / HTTP/1.1 get请求(是往服务器哪东西,而post是往服务器送东西)HTTP协议
/代表访问端口前面的地址,/index代表访问端口前面的加/index地址
HTTP协议版本
Host: 127.0.0.1:8080 (请求的服务器的主机名)
Connection: keep-alive (保持链接,直到完成任务后关闭)
Cache-Control: max-age=0 (缓存不失效)
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 (使用浏览器的内核)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 (可以接受的类型)
Accept-Encoding: gzip, deflate, br (可以接受的编码)
Accept-Language: zh-CN,zh;q=0.9
(接受的语言)
请求体:
bdsabdjsabjddas
响应头:
HTTP/1.1 200 OK
响应体:
自己看到的内容(服务端发回来的内容)
ps:
http: 默认端口是80
Https: 默认的端口是443
状态码
2XX: 200 (ok)
3XX: 302 304
4XX: 404(not found) 403(forbidden 禁止访问)
5XX: 500 (服务端代码错误) 502 (网关错误 bad gateway)
自定义一个简单的web框架
import socket import time def f1(): ### 静态网站 fp = open('index.html', 'r', encoding='utf-8') data = fp.read() fp.close() return bytes(data, encoding='utf-8') def f2(): ### 动态网站 fp = open('article.html', 'r', encoding='utf-8') data = fp.read() ctime = time.time() data = data.replace("@@content@@", str(ctime)) return bytes(data, encoding='utf-8') def f3(): ### 模板渲染(需要将html代码和mysql结果融合) import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', db='db1', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select id, name, depart_id from userinfo" cursor.execute(sql) res = cursor.fetchall() print(res) ''' [ {'id': 1, 'name': 'root1', 'depart_id': 1}, {'id': 4, 'name': 'root2', 'depart_id': 3}, {'id': 5, 'name': 'root3', 'depart_id': 5}, {'id': 6, 'name': 'root4', 'depart_id': 1}, {'id': 7, 'name': 'root5', 'depart_id': 3} ] ''' res_list = [] for user in res: res_str = "<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (user['id'], user['name'], user['depart_id']) res_list.append(res_str) s = "".join(res_list) fp = open('content.html', 'r', encoding='utf-8') data = fp.read() data = data.replace("@@content@@", s) return bytes(data, encoding='utf-8') #路由系统 routes = [ ('/xxx', f1), ('/ooo', f2), ('/hhh', f3), ('/kkk', f4), ] def run(): sk = socket.socket() sk.bind(('127.0.0.1', 8080)) sk.listen(5) while True: conn, addr = sk.accept() buf = conn.recv(8096) data = str(buf, encoding='utf-8') header_list = data.split(' ')[0].split(' ')[0] # 'GET / HTTP/1.1' uri = header_list.split(' ')[1] func_name = None for item in routes: if uri == item[0]: func_name = item[1] break if func_name: res = func_name() else: res = b"404 not found" conn.send(bytes('HTTP/1.1 200 OK ', encoding='utf-8')) conn.send(res) conn.close() if __name__ == '__main__': run()
补充:jinja2 第三方模板渲染工具
def f4(): import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', db='db1', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select id, name, depart_id from userinfo" cursor.execute(sql) users = cursor.fetchall() print(users) ''' [ {'id': 1, 'name': 'root1', 'depart_id': 1}, {'id': 4, 'name': 'root2', 'depart_id': 3}, {'id': 5, 'name': 'root3', 'depart_id': 5}, {'id': 6, 'name': 'root4', 'depart_id': 1}, {'id': 7, 'name': 'root5', 'depart_id': 3} ] ''' ### 模板渲染 fp = open('content-jinji2.html', 'r', encoding='utf-8') data = fp.read() from jinja2 import Template template = Template(data) data = template.render(users = users) return bytes(data, encoding='utf-8') routes = [ ('/xxx', f1), ('/ooo', f2), ('/hhh', f3), ('/kkk', f4), ]
html写法:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Title</title> </head> <body> <table border="1px"> <thead> <tr> <th>ID</th> <th>Name</th> <th>department_id</th> </tr> </thead> <tbody> {% for item in users %} <tr> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.depart_id}}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
自定义的web框架:
a. sokect 服务端
b. uri 和 函数的 对应关系(路由系统)
c. 将html代码和mysql的数据进行融合 (模板引擎渲染,自己定制规则 /使用第三方的工具)
web框架分类:
- a,b,c ----> tornado
- a(用第三方), b, c ----> django
- a(第三方),b, c(第三方) -----》 flask
Django基础
安装:
pip3 install django==1.11.10 -i https://pypi.tuna.tsinghua.edu.cn/simple
创建:
第一种(cmd):
先进D:> (python安装的盘)
django-admin startproject mysite(项目名称)
启动:
先找到manage.py文件
然后输入:python3 manage.py runserver 127.0.0.1:8090
第二种:
pycharm创建
目录介绍:
mysite:
mysite:
settings.py : 用户自定义的各种配置文件
urls.py : 路由文件
wsgi.py : 启动socket服务端的 文件
mange.py: 管理文件,如: python mange.py +各种命令(比如cmd中启动Django)
以后创建django完成之后:
a. 配置模板(html)文件路径(一般都配置好了):
'DIRS': [os.path.join(BASE_DIR, 'templates')]
b. 配置静态资源的文件(js, css, img)路径:
STATIC_URL = '/static/' 比如导入css样式,路径前面有/static/,那么就会进入这,然后跳转到下面去找
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'), (逗号不能少)
)
c. 注释中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
Django下面的红字:
第一个是 浏览器发的什么请求
第二个 是浏览器要请求的路由
第三个 是浏览器请求的协议
第四个 是服务器往浏览器返回的状态码
第五个 是服务器往浏览器发送的响应体的内容字节大小
写业务逻辑的话:
uri和函数的对应关系:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', index),
]
业务逻辑函数:
def index(request):
return render(request, "index.html",后面可以跟模板的渲染)
模板引擎的渲染:
{#变量替换#} <h2>{{ username }}</h2> {#列表替换#} <ul> <li>{{ mylist.0 }}</li> <li>{{ mylist.1 }}</li> <li>{{ mylist.2 }}</li> </ul> <hr> {#列表循环#} <ul> {% for item in mylist %} <li> {{ item }} </li> {% endfor %} </ul> <hr> {#字典循环#} <ul> {% for key, val in mydict.items %} <li> {{ key }} --------- {{ val }} </li> {% endfor %} </ul> <hr> {#循环key#} <ul> {% for key in mydict.keys %} <li> {{ key }} </li> {% endfor %} </ul>
案例:
def login(request): ### 使用的 是get请求 if request.method == 'GET': #request.method用户请求的方式 return render(request, 'login.html') #### 接收数据的时候 是post请求 else: username = request.POST.get('username') pwd = request.POST.get('pwd') ### 连数据库的方式查询 if username == 'zekai' and pwd == '123': return HttpResponse('登陆成功') else: return render(request, 'login.html #render 是将在Django拿到的html发给浏览器 urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^index/', index), url(r'^login/', login), # url(r'^new_login/', new_login), ]
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Title</title> </head> <body> <form action="/login/" method="post"> #action="" 里面填的是点击登录后,要跳转的url 用户名: <input type="text" name="username" > <br> 密码 : <input type="password" name="pwd"> <br> #"username" :'zekai', 点击登录后,会已这种形式传过去 #"pwd" :'123' <input type="submit" value="登陆"> </form> </body> </html>
ps:
字符串和字节的相互转换:
bytes(s,encoding='utf-8')
str(s, encoding='utf-8')