大家好,又见面了,我是你们的朋友全栈君。
www.baidu.com
,浏览器会自动补全协议(http),变为http://www.baidu.com
,现在部分网站都实现了HSTS
机制,服务器自动从http
协议重定向到https
协议javascript
脚本进行url跳转,仅设置href
=’绝对路径’,浏览器会自动使用当前url的协议、host和port,例如在https://tieba.baidu.com/index.html
网页中,点击一个超链接/f?kw=chinajoy
,会自动访问https://tieba.baidu.com/f?kw=chinajoy
hosts
文件也绑定了对应IP,若在本机中无法查到,那么就会去请求本地区域的域名服务器(通常是对应的网络运营商如电信),这个通过网络设置中的LDNS
去查找,如果还是没有找到的话,那么就去根域名服务器查找,这里有所有因特网上可访问的域名和IP对应信息(根域名服务器全球共13台)通过TCP协议的三次握手建立连接
建立连接后,客户端会通过TCP
依次、有序的发送一定大小的报文,其中包括了超时重传、阻塞窗口等等概念,用来保证数据包的完整、有序
SSL/TLS
加密,而SSL/TLS
是基于TCP
协议的,也就是http
协议报文包装成TCP
报文进行的加密,使用https
协议的话,如果本地没有证书和公钥,那么会从服务器获取证书并且进行验证,流程如下:
当前django
框架开发的web项目,主流使用的服务器架构是:nginx+uWSGI+django
nginx
监听公网IP的某个端口,例如80,接收到请求后,分2种情况处理请求:
nginx
直接获取到该资源,返回给用户nginx
就将请求转发到uWSGI
,使用的协议一般都是uwsgi
,性能最好注意:
reqeust
会分多个数据包进行发送,nginx
会缓存等待整个request
接收完成才调用uWSGI
https
,那么加密、解密都在nginx
中进行处理uWSGI
监听本机IP的某个端口,例如3308,接收到nginx
转发来的请求后,通过将http
协议转换为WSGI
协议,和django
程序之间进行通信
当django接受到一个请求时,会初始化一个WSGIHandler
,可以在项目下的wsgi.py
文件进行跟踪查看:
class WSGIHandler(base.BaseHandler):
request_class = WSGIRequest
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.load_middleware()
def __call__(self, environ, start_response):
set_script_prefix(get_script_name(environ))
signals.request_started.send(sender=self.__class__, environ=environ)
request = self.request_class(environ)
response = self.get_response(request)
......
它接受2个参数:
这个handler
控制了从请求到响应的整个过程,首先的就是加载django
的settings
配置,然后就是调用django的中间件开始操作
django操作中间件,首先会调用process_request
方法,该方法的作用是处理请求对象,它的参数是request
,返回有2种情况
返回response
之后的中间件及其业务逻辑都不会处理,直接回返回给浏览器
返回None
则表示会继续调用下一个中间件,处理下一个中间件中的逻辑
django项目默认有一些自带的中间件,如下:
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',
]
process_request
会从上往下依次调用MIDDLEWARE
中的中间件,注意:中间件的执行是有顺序的,所以我们一般自定义中间件的时候,我们都会将自定义的中间件放到列表最下面
通过urls.py
文件中的 urlpatterns
配置找到对应的 视图函数或者视图类的方法,如果没有找到匹配的方法,那么就会触发异常,由中间件的process_exception
进行处理
process_exception:在视图函数或中间件处理过程抛出异常时调用
参数:
返回:
process_exception
都不会触发,而是调用process_response
处理process_exception
处理我们通过路由调用视图之前,会调用中间件的process_view
方法进行预处理
process_view:视图预处理,在视图函数处理之前调用
参数:
返回:
process_response
处理process_view
处理调用对应的视图函数或视图类的方法处理request
,例如获取GET
和POST
参数,并且调用特定的模型对象执行数据库操作,如果没有数据库操作,那么就直接跳到我们后续的14步了
视图方法中,一般情况下都需要调用模型类进行数据操作,一般是通过模型的manager
管理类进行操作的,如:MyModel.objects.get(pk=1)
如果没有数据操作,那么这一步和下一步就忽略
如果django
通过模型类执行对数据库的增删改查,那么此时整个流程就会在对应的数据库中执行
视图方法获取到数据后:
context
字典当中,然后调用指定的template.html
,通过模板中的变量、标签和过滤器等,再结合传入的数据context
,会触发中间件的process_template_response
方法,最终渲染成HttpResponse
JsonResponse
、FileResponse
等redirect
,生成一个重定向的HttpResponse
,触发中间件的process_response
后,返回到客户端,结束该web请求的生命周期
调用中间件的 process_response
方法进行处理,最后一个中间件的process_response
执行完成后,返回到WSGIHandler
类中
WSGIHandler类获取到response后
response
的响应行和响应头,然后调用 start_response
返回http协议的 响应行和响应头 到uWSGI,这个 start_response
只能调用一次response
进行,否则就直接将response
作为http协议的body部分返回给uWSGI
uWSGI接收到django程序的返回后,将所有内容包装成http协议的内容后,通过uwsgi
协议返回给nginx
服务器处理
nginx获取到uWSGI的返回后,将response通过TCP协议返回给客户端
客户端接收到服务器的响应后,做对应的操作,例如:显示在浏览器中,或是javascript
的处理等至此,整个web请求的生命周期结束。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/164906.html原文链接:https://javaforall.cn