Web框架理解

目录

1.web框架理解
     2.http工作原理
     3.通过函数实现浏览器和服务端通信案例
     4.服务器程序和引用程序理解
     5.jinja2渲染模板案例
     6.Django简单说明

Web框架的本质

web应用本质上就是一个socket服务端,而浏览器就是一个socket客户端,这样就可以实现web框架了

socket web服务器

import socket
server = socket.socket()
server.bind((‘127.0.0.1‘,8000))
server.listen()
while True:
       conn, addr = sk.accept()
      data = conn.recv(8096)
      conn.send(b"OK")
      conn.close()  

http协议规定了浏览器发送消息或者服务器回复消息都要按照它规定来写

执行上面那段代码print(data)会得到以下结果

将\r\n替换成换行后的结果

GET / HTTP/1.1
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 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3355.4 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: csrftoken=CtHePYARJOKNx5oNVwxIteOJXpNyJ29L4bW4506YoVqFaIFFaHm0EWDZqKmw6Jm8

访问博客园返回浏览器的信息

由此可见首发信息都是按照一定格式来的,所以需要了解http协议工作模式

Http工作原理:

HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。

以下是 HTTP 请求/响应的步骤:

1. 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.luffycity.com。

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 地址;
2.解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
2.浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
4.服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5.释放 TCP连接;
6.浏览器将该 html 文本并显示内容;

  

http请求格式

http响应格式:

通过函数实现浏览器和服务端通信案例

自定义web框架按照http格式发送响应并根据url中的路径返回不同的内容

import socket
server = socket.socket()
server.bind((‘127.0.0.1‘,8000))
server.listen()
while True:
    conn,addr = server.accept()
    data = conn.recv(1024)
    data = data.decode(‘utf-8‘)
    print(data)

    url = data.split()[1]
    if url == ‘/home/‘:
        conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>home<h1>‘)
    elif url == ‘/index/‘:
        conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>index<h1>‘)
    else:
        conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>404 not found<h1>‘)
    conn.close()

基于函数实现url不同路径返回不同内容

import socket
server = socket.socket()
server.bind((‘127.0.0.1‘,8000))
server.listen()

def func(url):
    s = f"this is {url} page"
    return bytes(s,encoding="utf-8")

while True:
    conn,addr = server.accept()
    data = conn.recv(8096)
    data = str(data,encoding="utf-8")
    print(data)
    data1= data.split("\r\n")[0]
    url = data1.split()[1]

    conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>ok<h1>‘)   这个地方需要注意的一个点 闭合标签不能写/ 否则就当成普通字符串进行处理
    if url == "/index/":
        response = func(url)
    elif url == "/home/":
        response = func(url)
    else:
        response = b"404 not found"

    conn.send(response)
    conn.close()

实现url不同路径返回不同内容函数进阶版

import socket
server =socket.socket()
server.bind((‘127.0.0.1‘,8000))
server.listen()

def index(url):
    s = f"This is {url} page"
    return bytes(s,encoding="utf-8")

def home(url):
    s = f"This is {url} page"
    return bytes(s,encoding="utf-8")

list1 = [("/index/",index),
         ("/index/",home)]

while True:
    conn,addr = server.accept()
    data = conn.recv(8096)
    data = str(data,encoding="utf-8")
    print(data)
    data1= data.split("\r\n")[0]
    url = data1.split()[1]
    conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>ok<h1>‘)
    func = None
    for item in list1:
        if item[0] == url:
            func = item[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found"
    conn.send(response)
    conn.close()

返回具体的html文件

import socket
server =socket.socket()
server.bind((‘127.0.0.1‘,8000))
server.listen()

def index(url):
    with open("template/index.html","r",encoding="utf-8") as f:
        s = f.read()
    return bytes(s,encoding="utf-8")

def home(url):
    with open("template/home.html", "r", encoding="utf-8") as f:
        s = f.read()
    return bytes(s,encoding="utf-8")

list1 = [("/index/",index),
         ("/home/",home)]

while True:
    conn,addr = server.accept()
    data = conn.recv(8096)
    data = str(data,encoding="utf-8")
    print(data)
    data1= data.split("\r\n")[0]
    url = data1.split()[1]
    conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>ok<h1>‘)
    func = None
    for item in list1:
        if item[0] == url:
            func = item[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found"
    conn.send(response)
    conn.close()

网页动态

import socket
server =socket.socket()
server.bind((‘127.0.0.1‘,8000))
server.listen()

def index(url):
    with open("template/index.html","r",encoding="utf-8") as f:
        s = f.read()
    return bytes(s,encoding="utf-8")

def home(url):
    with open("template/home.html", "r", encoding="utf-8") as f:
        s = f.read()
    return bytes(s,encoding="utf-8")

def timer(url):
    import time
    with open("template/timer.html","r",encoding="utf-8") as f:
        s = f.read()
        s = s.replace(‘@@[email protected]@‘,time.strftime("%Y-%m-%d %H:%M:%S"))
        return bytes(s,encoding="utf-8")

list1 = [("/index/",index),
         ("/home/",home),
         ("/time/",timer)]

while True:
    conn,addr = server.accept()
    data = conn.recv(8096)
    data = str(data,encoding="utf-8")
    print(data)
    data1= data.split("\r\n")[0]
    url = data1.split()[1]
    conn.send(b‘HTTP/1.1 200 OK\r\n\r\n<h1>ok<h1>‘)
    func = None
    for item in list1:
        if item[0] == url:
            func = item[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found"
    conn.send(response)
    conn.close()

服务器程序和应用程序

对于真实开发中的python web程序来说,一般会分为服务器程序和应用程序

服务器程序负责对socket服务端进行封装,并在请求到来时,对请求的各种数据进行处理

应用程序则负责处理具体的逻辑,为了方便应用程序开发,就出现了众多的web框架。

应用程序必须和服务程序配合才能为用户提供服务。

WSGI (Web Server Gateway Interface)是一种规范,定义了使用Python编写的Web应用程序与web服务程序之间的接口格式,实现了web应用程序和web服务程序间的解耦

常用的WSGI服务器有uWSGI、Gunicorn、而python标准库提供的WSGI叫wsgiref,Django开发环境用的就是这个模块来做的服务器。

wsgiref写web框架的socket server例子:

from wsgiref.simple_server import make_server

def index(url):
    with open("template/index.html","r",encoding="utf-8") as f:
        s = f.read()
    return bytes(s,encoding="utf-8")

def home(url):
    with open("template/home.html", "r", encoding="utf-8") as f:
        s = f.read()
    return bytes(s,encoding="utf-8")

def timer(url):
    import time
    with open("template/timer.html","r",encoding="utf-8") as f:
        s = f.read()
        s = s.replace(‘@@[email protected]@‘,time.strftime("%Y-%m-%d %H:%M:%S"))
        return bytes(s,encoding="utf-8")

list1 = [("/index/",index),
         ("/home/",home),
         ("/time/",timer)]
#
def run_server(environ,start_response):
    start_response(‘200 ok‘,[(‘Content-Type‘,‘text/html;charset=utf8‘),])
    url =environ[‘PATH_INFO‘]
    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‘,8000,run_server)
    print("I am waitting for you at 8000")
    httpd.serve_forever()

使用jinja2渲染

python代码
from wsgiref.simple_server import make_server
from jinja2 import Template

def index(url):
    with open(‘template/index2.html‘,"r",encoding="utf-8") as f:
        data = f.read()
        template = Template(data) #生成模板
        #把数据填充到模板中
        ret = template.render({‘name‘: ‘xxx‘, ‘hobby_list‘: [‘抽烟‘, ‘喝酒‘, ‘烫头‘]})
    return bytes(ret,encoding="utf-8")

def home(url):
    with open("home.html", "r", encoding="utf8") as f:
        s = f.read()
    return bytes(s, encoding="utf8")

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()

要渲染的html文件

<!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>

Django简介

安装
pip3 install django==1.11.22

创建一个Django项目
django-admin startproject mysite02

目录简介
mysite/
├── manage.py  # 管理文件
└── mysite  # 项目目录
    ├── __init__.py
    ├── settings.py  # 配置
    ├── urls.py  # 路由 --> URL和函数的对应关系
    └── wsgi.py  # runserver命令就使用wsgiref模块做简单的web server

运行django项目
python manage.py runserver 127.0.0.1:8000

模板文件配置
TEMPLATES = [
    {
        ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘,
        ‘DIRS‘: [os.path.join(BASE_DIR, "template")],  # template文件夹位置
        ‘APP_DIRS‘: True,
        ‘OPTIONS‘: {
            ‘context_processors‘: [
                ‘django.template.context_processors.debug‘,
                ‘django.template.context_processors.request‘,
                ‘django.contrib.auth.context_processors.auth‘,
                ‘django.contrib.messages.context_processors.messages‘,
            ],
        },
    },
]

静态文件配置
STATIC_URL = ‘/static/‘  # HTML中使用的静态文件夹前缀
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),  # 静态文件存放位置
]

方便提交表单暂时禁用csrf中间件

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基础三要素

from django.shortcuts import HttpResponse, render, redirect

HttpResponse 内部传入一个字符串参数,返回给浏览器
def index(request):
    # 业务逻辑代码
    return HttpResponse("OK")

render除request参数外还接受一个待渲染的模板和一个保存具体数据的字典参数将数据填充进模板文件,最后把结果返回给浏览器(类似上面的jinja2)
def index(request):
    # 业务逻辑代码
    return render(request, "index.html", {"name": "xxx", "hobby": ["烫头", "泡吧"]})

redirect接收一个URL参数,表示跳转到指定的URL
def index(request):
    # 业务逻辑代码
    return redirect("/home/")

此博客大部分内容是参考老师的,主要为了自己加深理解......

原文地址:https://www.cnblogs.com/guniang/p/11188713.html

时间: 2024-08-29 17:03:10

Web框架理解的相关文章

Spring 4 官方文档学习(十三)集成其他web框架

重点是通用配置,非常建议看一下!有助于理解Spring的ApplicationContext与Servlet Container的关系! 1.介绍 Spring Web Flow SWF目标是成为web应用页面flow管理的最佳解决方案. SWF集成了现有的框架,如Spring MVC 和 JSF,在Servlet和Portlet环境中.如果你有一个(或多个)业务处理,且 受益于会话模型而非纯请求模型,那SWF可能就是解决方案. SWF允许捕获逻辑页面flows,并将其作为自包容的模块 -- 可

SSM框架理解(转)

SSM框架理解 最近两星期一直在学JavaEE的MVC框架,因为之前学校开的JavaEE课程就一直学的吊儿郎当的,所以现在真正需要掌握就非常手忙脚乱,在此记录下这段时间学习的感悟,如有错误,希望大牛毫不客气地指出. SpringSpring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象.Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地`new`一个对象,而是让Spring框架帮你来完成这一切. SpringMVCSp

一 什么是web框架?

Django-1 一 什么是web框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200

从零开始搭建论坛(一):Web服务器与Web框架

之前用 Django 做过一个小的站点,感觉Django太过笨重,于是就准备换一个比较轻量级的 Web 框架来玩玩.Web.py 作者已经挂掉,项目好久没有更新,所以不准备用它.而 Flask 也是一个成熟的轻量级 Web 框架,在 github 上有众多的 Star 和 Fork,文档和扩展也很丰富,值得学习. 学习一个框架最好的方式就是用框架做一个项目,在实战中理解掌握框架.这里我用 Flask 框架,使用 Mysql 数据库做了一个论坛系统.麻雀虽小,五脏俱全,论坛效果图如下: 下面是论坛

从零构建一个简单的 Python Web框架

为什么你想要自己构建一个 web 框架呢?我想,原因有以下几点: 你有一个新奇的想法,觉得将会取代其他的框架 你想要获得一些名气 你遇到的问题很独特,以至于现有的框架不太合适 你对 web 框架是如何工作的很感兴趣,因为你想要成为一位更好的 web 开发者. 接下来的笔墨将着重于最后一点.这篇文章旨在通过对设计和实现过程一步一步的阐述告诉读者,我在完成一个小型的服务器和框架之后学到了什么.你可以在这个代码仓库中找到这个项目的完整代码. 我希望这篇文章可以鼓励更多的人来尝试,因为这确实很有趣.它让

13.python中web框架概念的引入。

一.什么是web框架? 框架,就是一个为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回. 如果要动态生成HTML,就需要把上述步骤自己来实现.不过,接受HTTP请求.解析HTTP请求.发

web框架以及MVC、MTV

h3 { background-color: palegreen } 本篇内容概要 ----原始web框架 ----自定义web框架 ----mvc和mtv 一.web框架的本质 对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器就是一个socket客户端 简单的说就是,socket传入数据,之后后面是业务逻辑处理程序 画得不好,理解就好 二.引入WSGI 由于web框架包括两部分 1.socket 2.逻辑处理 有些框架只有逻辑处理,没有socket,如flask.bot

Resty 一款极简的restful轻量级的web框架

https://github.com/Dreampie/Resty Resty 一款极简的restful轻量级的web框架 开发文档 如果你还不是很了解restful,或者认为restful只是一种规范不具有实际意义,推荐一篇osc两年前的文章:RESTful API 设计最佳实践 和 Infoq的一篇极其理论的文章 理解本真的REST架构风格 虽然有点老,介绍的也很简单,大家权当了解,restful的更多好处,还请google 拥有jfinal/activejdbc一样的activerecor

蜗牛历险记(二) Web框架(下)

Web框架第三篇--缓存篇 缓存的优劣很大程度上决定了框架的效率,一个有节操的缓存它应该是高效的,利用率高的,具备更多扩展功能的. 一.介绍之前 计算机各个硬件的运行效率是不一样的,CPU>>一级缓存>>二级缓存>>内存>>硬盘.如何提供CPU.一级缓存.二级缓存的使用率是操作系统的课题.我们需要做的就是如何提高内存使用效率,减少磁盘IO. 目前我们熟知的跟缓存有关的产品:.Net Mvc的CacheManager,Redis,Memcached 二.使用范