HTTP、BS架构
Django底层原理
快捷键
⽅向键
⽅向键本键如果活动选项是或⽂件则为移动焦点;
⽅向键 + Win键(简称Win键)使窗⼝全屏、最⼩化、靠左半边、靠右半边(部分版本不⽀持);
⽅向键+Shift键将连续的⽂字或⽂件选中
⽅向键(左右)+Ctrl键在英⽂单词或中⽂词语间跳跃
⽅向键(上下)+Ctrl键在段落开头间跳跃
按Home(定位到⾏⾸)然后按Shift+End(⾏尾)或者然后按Shift+↓(下⼀⾏这个位置)
或者按End(定位到⾏尾)然后按Shift+Home
ctrl
Ctrl+b 粗体 Bold
Ctrl+e 居中对齐 Encenter
Ctrl+f 查 Find
Ctrl+h 替换 Huan
Ctrl+k 超级链接 King Link
win
Win键+E打开Windows资源管理器Explorer【即我的电脑、计算机】
Win键+R:运⾏
Win键+Shift+S:Windows ⾃带截图
win键+PrtScSysRq键快速截屏
HTTP
超⽂本传输协议(英⽂:HyperText Transfer Protocol,缩写:HTTP)是⼀种⽤于分布式、协作式和超媒体信息系统的应⽤层协议。HTTP是万维⽹WEB的数据通信的基础。
现今⼴泛使⽤的⼀个版本——HTTP 1.1(已更新⾄2.0)
HTTP⼯作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页⾯,以及服务器如何把Web页⾯传送给客户端。
HTTP协议采⽤了请求/响应模型。
客户端向服务器发送⼀个请求报⽂,请求报⽂包含请求的⽅法、URL、协议版本、请求头部和请求数据。服务器以⼀个状态⾏作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
响应报⽂:⽐如"HTTP/1.1 200 OK"
以下是 HTTP 请求/响应的步骤:
1. 客户端连接到Web服务器
⼀个HTTP客户端,通常是浏览器,与Web服务器的HTTP端⼝(默认为80)建⽴⼀个TCP套接字连接。例如,。
2. 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送⼀个⽂本的请求报⽂,⼀个请求报⽂由请求⾏、请求头部、空⾏和请求数据4部分组成。
3. 服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。⼀个响应由状态⾏、响应头部、空⾏和响应数据4部分组成。
4. 释放连接TCP连接
若connection 模式为 close(⽆连接),则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若 connection 模式为 keepalive(短连接),则该连接会保持⼀段时间,在该时间内可以继续接收请求;
5. 客户端浏览器解析HTML内容
客户端浏览器⾸先解析状态⾏,查看表明请求是否成功的状态代码。然后解析每⼀个响应头,响应头告知以下为若⼲字节的HTML⽂档和⽂档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进⾏格式化,并在浏览器窗⼝中显⽰。
例如:在浏览器地址栏键⼊URL,按下回车之后会经历以下流程:
1. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
、
域名(英语:Domain Name),⼜称⽹域,是由⼀串⽤点分隔的名字组成的Internet上某⼀台计算机或计算机组的名称,⽤于在数据传输时对计算机的定位标识(有时也指地理位置)。
由于IP地址具有不⽅便记忆并且不能显⽰地址组织的名称和性质等缺点,⼈们设计出了域名,并通过域名服务器(DNS,Domain Name System)来将域名和
IP地址相互映射,使⼈更⽅便地访问互联⽹,⽽不⽤去记住能够被机器直接读取的IP地址数串。
2. 解析出 IP 地址后,根据该 IP 地址和默认端⼝ 80,和服务器建⽴TCP连接;
3. 浏览器发出读取⽂件(URL 中域名后⾯部分对应的路径(⽂件))的HTTP 请求,该请求报⽂作为 TCP 三次握⼿中第三次握⼿(由客户端发送)时的报⽂数据发送给服
务器;
4. 服务器对浏览器请求作出响应,并把对应的 html ⽂本发送给浏览器;
5. 释放 TCP连接;
6. 浏览器将该 html ⽂本渲染并显⽰内容;
HTTP特点:
基于请求-响应的模式
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建⽴通信的,服务器端在没有接收到请求之前不会发送响应
⽆状态保存
概念:
HTTP是⼀种不保存状态,即⽆状态(stateless)协议,即HTTP协议⾃⾝不对请求和响应之间的通信状态进⾏保存。
只要连接中断,就撤销当前所有信息,即每次开始时都是个完全空⽩的状态
⽬的:
为了更快地处理⼤量事务,确保协议的可伸缩性,⽽特意把HTTP协议设计成如此简单的。
弊端:
信息的不存储,对于必须要存储某些信息的⽹站来说,意味着:
我输⼊⼀个⽹页并回车,⼀个套接字返回我要访问的html,然后他就⾛了,然后当我要进⾏登陆操作时,⼜来了⼀个套接字接待我,给我返回登陆的⽹页,然后他也⾛了。我在输⼊完信息后回车进⾏登陆,⼜⼀个套接字过来拿着基于上述情况,cookie由此诞⽣。
⽆连接
概念:
⽆连接的含义是限制每次连接只处理⼀个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。
⽬的:
采⽤这种⽅式可以节省传输时间,并且可以提⾼并发性能,不能和每个⽤户建⽴长久的连接,请求⼀次响应⼀次,服务端和客户端就中断了。
优势:
适⽤于重浏览型⽹页,腾出线程来接待新⽤户,防⽌占⽤套接字不发请求的⽤户。
短连接:
概念:
HTTP/1.1 版本之后,采⽤的是短连接的⽅式:即套接字响应完后,不会马上关闭,⽽是等待⼏秒钟的时间(程序员可以⾃⾏设定),如果客户端在这段时间内
没有响应的话,才会断开。
⽬的
这样做的主要⽬的还是为了节省时间,因为重新创建套接字也是需要时间的,⽬前默认3s左右。对于⼀个连续操作的客户端来说,如果他在短时间内点击了html
中的很多选项,这样每次服务器都需要创建⼀个套接字来接待他,仅创建套接字的时间就⾜以拖垮效率。
⽽对于⼀个操作间隔很长的客户端来说,⽆连接很明显是个⾜够优秀的选择
短连接等待时间
⽹站根据⾃⼰⽹站⽤户的⾏为来分析统计出⼀个最优的等待时间。
优势:
适⽤于强操作性⽹页,可以防⽌单个⽤户短时间就占⽤多个套接字(因为⽆连接的⽅式,套接字响应完请求就⾃⾏关闭了,所以新的请求就要重新建⽴套接
字)。
因此,⽆连接、短连接没有绝对的优劣,主要还是看客户端需求。
HTTP请求⽅法
get 拿数据
post 发数据
报⽂格式
请求报⽂
响应报⽂
通过GET⽅式提交数据时,请求数据(页⾯提交的信息)会放在原路径后,并与原路径组成⼀个新的路径部分,因此get⽅式提交时路径部分不⽌有路径,且后⾯的请求数
据部分⼀定为空。
这种形式还会出现⼀个问题就是:
客户端第⼀次访问服务器时,通常是以域名的形式访问的,之后就通过点击超链接或敲回车⾃动转载⽹页的形式访问服务器的其他页⾯。
上述后者是以URL{域名(或ip)+路径}的形式访问服务器的,这就意味着,页⾯在访问服务器时,域名+路径会直接显⽰在浏览器⽹址栏,即⽤户的请求数据会
以明⽂形式显⽰在⽹址栏,这对于⽤户的个⼈数据等信息来说是不能接受的。
GET⽅式以?分割路径和请求数据,请求数据中的参数之间以&相连,如EditBook?name=test1&id=123456.(请求头⾥⾯那个content-type做的这种参数形式,后⾯讲)
POST⽅法是把页⾯提交的数据放在HTTP包的请求数据中。
GET提交的数据⼤⼩有限制(因为浏览器对URL的长度有限制),⽽POST⽅法提交的数据没有限制.
GET与POST请求在服务端获取请求数据⽅式不同,就是我们⾃⼰在服务端取请求数据的时候的⽅式不同了,这句废话昂。
HTTP状态码
所有HTTP响应的第⼀⾏都是状态⾏,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。⽐如"HTTP/1.1 200 OK"
状态代码的第⼀个数字代表当前响应的类型:
1xx消息——请求已被服务器接收,继续处理
2xx成功——请求已成功被服务器接收、理解、并接受(没问题)
3xx重定向——需要后续操作才能完成这⼀请求
4xx请求错误——请求含有词法错误或者⽆法被执⾏(客户端请求出现问题)
5xx服务器错误——服务器在处理某个正确请求时发⽣错误(服务器出现问题)
URL
超⽂本传输协议(HTTP)的统⼀资源定位符将从因特⽹获取信息的五个基本元素包括在⼀个简单的地址中(即⼀个完整的⽹页):
传送协议(http/https(http基础上进⾏加密,提升安全性))。
层级URL标记符号(为[//],固定不变)
访问资源需要的凭证信息(可省略)
服务器。(通常为域名,有时为IP地址)
端⼝号。(以数字⽅式表⽰,若为HTTP的默认值“:80”可省略)
路径。(以“/”字符区别路径中的每⼀个⽬录名称,第⼀个/前就是域名(或IP)
查询。(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)
⽚段。以“#”字符为起点
以www.luffycity:80/news/index.html?id=250&page=1 为例,
其中:
http,是协议;
www.luffycity,是服务器;
80,是服务器上的默认⽹络端⼝号,默认不显⽰;
/news/index.html,是路径(URI:直接定位到对应的资源);
id=250&page=1,是查询。
⼤多数⽹页浏览器不要求⽤户输⼊⽹页中“”的部分,因为绝⼤多数⽹页内容是超⽂本传输协议⽂件。同样,“80”是超⽂本传输协议⽂件的常⽤端⼝号,因此⼀般也不必写明。⼀般来说⽤户只要键⼊统⼀资源定位符的⼀部分(www.luffycity:8
由于超⽂本传输协议允许服务器将浏览器重定向到另⼀个⽹页地址,因此许多服务器允许⽤户省略⽹页地址中的部分,⽐如 www。从技术上来说这样省略后的⽹页地址实际上是⼀个不同的⽹页地址,浏览器本⾝⽆法决定这个新地址是否通,服务器必须完成重定向的任务。
浏览器对页⾯进⾏渲染时,需要html⽂件中通过各种⽅式引⽤的所有素材以及⽹页的图标,并且这个过程是以异步的形式向服务器发送请求的(遇到第⼀个需要的素材,就给服务器发请求说我要,然后html中的代码继续往下⾛)
rb形式发送⽂件数据时,发送的只有⽂档⾥的内容,⽂件的外壳跟名字都没有被发送
函数版web框架
from threading import Thread
import socket
server = socket.socket()
server.bind(('127.0.0.1',8001))
server.listen()
def html():
with open('home.html', 'rb') as f:
to_client_data = f.read()
return to_client_data
def css():
with open('home.css', 'rb') as f:
to_client_data = f.read()
return to_client_data
def js():
with open('home.js', 'rb') as f:
to_client_data = f.read()
return to_client_data
def jpg():
url编码和utf8区别with open('1.jpg', 'rb') as f:
to_client_data = f.read()
return to_client_data
def ico():
with open('xx1.ico', 'rb') as f:
to_client_data = f.read()
return to_client_data
url_patterns = [
('/',html),
('/home.css',css),
('/home.js',js),
('/1.jpg',jpg),
('/favicon.ico',ico),
]
while 1:
conn,addr = server.accept()
from_client_msg = v(1024).decode('utf-8')
# print(from_client_msg)
# print(from_client_msg.decode('utf-8'))
request_path = from_client_msg.split(' ')[1]
# 拿到⽤户的访问路径
print(request_path)
conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
for i in url_patterns:
if i[0] == request_path:
# 进⾏信息⽐对,你要访问的路径在我的url-func关系中,就调⽤对应的函数给他返回对应页⾯。
to_client_data = i[1]()
conn.send(to_client_data)
conn.close()
server.close()
并发版web框架
from threading import Thread
import socket
server = socket.socket()
server.bind(('127.0.0.1',8001))
server.listen()
def html(conn):
with open('home.html', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
# return to_client_data
def css(conn):
with open('home.css', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
def js(conn):
with open('home.js', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
def jpg(conn):
with open('1.jpg', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
def ico(conn):
with open('xx1.ico', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
url_patterns = [
('/',html),
('/home.css',css),
('/home.js',js),
('/1.jpg',jpg),
('/favicon.ico',ico),
]
while 1:
conn,addr = server.accept()
from_client_msg = v(1024).decode('utf-8')
request_path = from_client_msg.split(' ')[1]
print(request_path)
conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
for i in url_patterns:
if i[0] == request_path:
target_thread = Thread(target=i[1],args=(conn,))
# to_client_data = i[1]()
target_thread.start()
server.close()
# 注意:这⾥不能跟函数web框架⼀样在循环外关闭套接字、服务器
# 因为我的代码⾥只有⼀个变量名。通俗点形容:当⼀个客户来访问服务器,我就创建⼀个线程给他个名字叫:conn,并让她去服务这个客户,他俩离开后,如果⼜来⼀个⽤户,我就再创建⼀个线程,并且把之前那个线程的名字给拿⾛给这 # 但当其中⼀个线程先运⾏完后,他就会执⾏循环外的conn.close(),这时如果正好创建了⼀个线程,把名字也给了,但是还没来得及去服务,他就被辞职了,这时没⼈服务⽤户了,程序就出错了!⽽且,在辞职完conn后,还要关门停⽌营动态页⾯版web框架
动态页⾯的意思是:同⼀个url,我每次打开时都不同于之前。⽽⾮,带闪图、动态等重复变化的页⾯。
from threading import Thread
import socket
import time
server = socket.socket()
server.bind(('127.0.0.1',8001))
server.listen()
def html(conn):
current_time = time.time()
# import pymysql
with open('home.html', 'r',encoding='utf-8') as f:
to_client_data = f.read()
to_client_data = to_place('%xxoo%',str(current_time))
conn.send(to_de('utf-8'))
conn.close()
# return to_client_data
def css(conn):
with open('home.css', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
def js(conn):
with open('home.js', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
def jpg(conn):
with open('1.jpg', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
def ico(conn):
with open('xx1.ico', 'rb') as f:
to_client_data = f.read()
conn.send(to_client_data)
conn.close()
url_patterns = [
('/',html),
('/home.css',css),
('/home.js',js),
('/1.jpg',jpg),
('/favicon.ico',ico),
]
while 1:
conn,addr = server.accept()
from_client_msg = v(1024).decode('utf-8')
request_path = from_client_msg.split(' ')[1]
print(request_path)
conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
for i in url_patterns:
if i[0] == request_path:
target_thread = Thread(target=i[1],args=(conn,))
# to_client_data = i[1]()
target_thread.start()
server.close()
wsgiref版web框架
wsgiref模块是对socket的封装,其内部的environ是对http信息进⾏了切割,并整理成⼀个字典,想要⽤户的什么数据,只要知道这个数据对应的键名就可以直接拿到了,⽽
什么数据对应什么键都是其内部定义好了的,所以⽤起来很⽅便。
Django中也有可以实现wsgiref模块功能的元素,也是通过某些功能直接将http信息做好了切割,保存,通过指定⽅式去拿指定信息就可以了。
from wsgiref.simple_server import make_server
url_patterns = [('/index',index),]
def index():
with open('html', 'rb') as f:
to_client_data = f.read()
return to_client_data
def application(environ, start_response):
"""
:param environ: 封装了所有的http协议相关信息--⼀个字典{'path_info':'/'}
:param start_response:
:return:
"""
request_path = environ['PATH_INFO']
# 通过固定键名'PATH_INFO'直接拿到⽤户的请求路径
for i in url_patterns:
if i[0] == request_path:
ret = i[1]()
start_response('200 OK', [('k1','v1'),])
# print(environ)
# print(environ['PATH_INFO'])
return [ret]
httpd = make_server('127.0.0.1', 8080, application)
httpd.serve_forever()
B/S概念
随着Internet和WWW的流⾏,以往的主机/终端和C/S都⽆法满⾜当前的全球⽹络开放、互连、信息随处可见和信息共享的新要求,于是就出现了B/S架构,即浏览器/服务器结构。它是C/S架构的⼀种改进,可以说属于三层C/S架构。主要是利⽤了不断成熟的WWW浏览器技术,⽤通⽤浏览器就实现了原来需要复杂专⽤软件才能实现的强⼤功能,并节约了开发成本,是⼀种全新的软件系统构造技术。
结构:
第⼀层是浏览器,即客户端,只有简单的输⼊输出功能,处理极少部分的事务逻辑。由于客户不需要安装客户端,只要有浏览器就能上⽹浏览,所以它⾯向的是⼤范围的⽤户,所以界⾯设计得⽐较简单,通⽤。
第⼆层是WEB服务器,扮演着信息传送的⾓⾊。当⽤户想要访问数据库时,就会⾸先向WEB服务器发送请求,WEB服务器统⼀请求后会向数据库服务器发送访问数据库的请求,这个请求是以SQL语句实现的。
第三层是数据库服务器,他扮演着重要的⾓⾊,因为它存放着⼤量的数据。当数据库服务器收到了WEB服务器的请求后,会对SQL语句进⾏处理,并将返回的结果发送给WEB服务器,接下来,WEB服务器将收到的数据结果转换为HTML⽂本形式发送给浏览器,也就是我们打开浏览器看到的界⾯。
原理
B/S架构采取浏览器请求,服务器响应的⼯作模式。
⽤户可以通过浏览器去访问Internet上由Web服务器产⽣的⽂本、数据、图⽚、动画、视频点播和声⾳等信息;
⽽每⼀个Web服务器⼜可以通过各种⽅式与数据库服务器连接,⼤量的数据实际存放在数据库服务器中;
从Web服务器上下载程序到本地来执⾏,在下载过程中若遇到与数据库有关的指令,由Web服务器交给数据库服务器来解释执⾏,并返回给Web服务器,Web服务器⼜返回给⽤户。在这种结构中,将许许多多的⽹连接到⼀块,形成⼀个巨⼤的⽹,即全球⽹。⽽各个企业可以在此结构的基础上建⽴⾃⼰的Internet。
在 B/S 模式中,⽤户是通过浏览器针对许多分布于⽹络上的服务器进⾏请求访问的,浏览器的请求通过服务器进⾏处理,并将处理结果以及相应的信息返回给浏览器,其他的数据加⼯、请求全部都是由Web Server完成的。通过该框架结构以及植⼊于操作系统内部的浏览器,该结构已经成为了当今软件应⽤的主流结构模式。
B/S优缺点
B/S架构最⼤的优点是总体拥有成本低、维护⽅便、分布性强、开发简单,可以不⽤安装任何专门的软件就能实现在任何地⽅进⾏操作,客户端零维护,系统的扩展⾮常容易,只要有⼀台能上⽹的电脑就能使⽤。
最⼤的缺点就是通信开销⼤、系统和数据的安全性较难保障。
C/S与B/S
在响应速度,⽤户界⾯,数据安全等⽅⾯,C/S强于B/S,但是在业务扩展和适⽤www条件下,B/S明显胜过C/S。可以这么说,B/S的强项就是C/S的弱项,反之亦然。它们各有优缺点,相互⽆法取代。
C/S结构与B/S结构两种模式各⾃拥有其特⾊优势,在不同的系统环境与操作平台下,选择较为接近或交叉进⾏混合模式的使⽤,可以保证数据的敏感性、安全性和稳定发展,还可以加强对数据库的修改与新增记录的操作。对客户端程序进⾏保护,提⾼资源数据的交互性能,实现系统维护成本较低、维护⽅式较简便、布局更合理、⽹络数据使⽤效率较⾼的⽬的,采⽤C/S与B/S混合模式才是最佳⽅案。
C/S与B/S不同点
C/S B/S
硬件环境专⽤⽹络⼴域⽹
安全要求⾯向相对固定的⽤户信息安全的控制能⼒强⾯向不可知的⽤户对安全的控制能⼒相对较弱
程序架构更加注重流程系统运⾏速度可较少考虑对安全以及访问速度都要多重的考虑,是发展趋势
软件重⽤差好
系统维护升级难开销⼩,⽅便升级
处理问题集中分散
⽤户接⼝与操作系统关系密切跨平台,与浏览器相关
信息流交互性低交互密集
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论