第一章 web框架的本质

1.1 本质

1. 实现socket服务器

import socket
sk = socket.socket()
sk.bind(('127.0.0.1', 8000))
sk.listen(5)
while True:
    con, addr = sk.accept()
  # 接收数据
  msg = con.recv(1024).decode('utf-8')
  # 返回数据
  con.send(b'ok')
  # 断开链接
  con.close()
sk.close()

 

2. 返回html文件

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
from socket import SOL_SOCKET, SO_REUSEADDR
sk = socket.socket()
sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 8000))
sk.listen(5)

def home(url):
    with open('./html/home.html', 'rb') as f:
        data = f.read()
    return data

def index(url):
    with open('./html/index.html', 'rb') as f:
        data = f.read()
    return data

url_li = {'/index': index, '/home': home}

while True:
    con, addr = sk.accept()
    data = con.recv(1024).decode('utf-8')
    url = data.split()[1]
    # 响应头
    con.send(b'HTTP/1.1 200 ok\r\n\r\n')
    if url_li.get(url):
        data = url_li[url](url)
    else:
        data = b'404 not found'
    con.send(data)
    con.close()
sk.close()

 

3. 返回动态网页

# 返回动态页面
def home(url):
    with open('./html/home.html', 'r', encoding='utf-8') as f:
        data = f.read().replace('@@time@@', time.strftime('%H:%M:%S')).encode('utf-8')
    return data
url_li = {'/home': home}

while True:
    con, addr = sk.accept()
    data = con.recv(1024).decode('utf-8')
    url = data.split()[1]
    con.send(b'HTTP/1.1 200 ok\r\n\r\n')
    if url_li.get(url):
        data = url_li[url](url)
    else:
        data = b'404 not found'
    con.send(data)
    con.close()
sk.close()

 

1.2 HTTP

1. http简介

  1. 超文本传输协议(英文:HyperText Transfer Protocol,HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议HTTP是万维网的数据通信的基础。HTTP有很多应用,但最著名的是用于web浏览器和web服务器之间的双工通信。

  2. HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本——HTTP 1.1。

  3. 2014年12月,互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。 HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP 1.1成为HTTP的实现标准。

2. 协议概述

  1. HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80,https默认时443)。我们称这个客户端为用户代理程序(user agent)。应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。在用户代理和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。

  2. 尽管TCP/IP协议是互联网上最流行的应用,HTTP协议中,并没有规定必须使用它或它支持的层。事实上,HTTP可以在任何互联网协议上,或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用。因此也就是其在TCP/IP协议族使用TCP作为其传输层。

  3. 通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。一旦收到请求,服务器会向客户端返回一个状态,比如"HTTP/1.1 200 OK",以及返回的内容,如请求的文件、错误消息、或者其它信息。

3. 工作原理

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

  2. 以下是 HTTP 请求/响应的步骤(5)

    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的语法对其进行格式化,并在浏览器窗口中显示。

4. 请求方法

  • HTTP/1.1 协议规定了八种方法(动作)

  • HTTP/1.1协议中共定义了八种方法(也叫“动作”)来以不同方式操作指定的资源:

  1. GET

    • 向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。

  2. HEAD

    • 与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)

  3. POST

    • 向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。

  4. PUT

    • 指定资源位置上传其最新内容。

  5. DELETE

    • 请求服务器删除Request-URI所标识的资源

  6. TRACE

    • 回显服务器收到的请求,主要用于测试或诊断。

  7. OPTIONS

    • 这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。

  8. CONNECT

    • HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。

Note1(2)

  1. 方法名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。

  2. HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。当然,所有的方法支持的实现都应当匹配下述的方法各自的语义定义。此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法。例如PATCH(由 RFC 5789 指定的方法)用于将局部修改应用到资源

5. 状态码

  1. 所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔

  2. 状态代码的第一个数字代表当前响应的类型

    1. 1xx消息——请求已被服务器接收,继续处理

      1. 101 switching procotols

      2. 102 processing 扩展的状态

    2. 2xx成功——请求已成功被服务器接收、理解、并接收

    3. 3xx重定向——需要后续操作才能完成这一请求,当前服务器无法处理,响应另一个服务地址

    4. 4xx请求错误——请求含有词法错误或者无法被执行,没有该资源,401表示认证错误、402 预留、403(forbidden)表示权限不够、405 method not allow

    5. 5xx服务器错误——服务器在处理某个正确请求时发生错误,500服务端,代码问题。

  3. 虽然 RFC 2616 中已经推荐了描述状态的短语,例如"200 OK","404 Not Found",但是WEB开发者仍然能够自行决定采用何种短语,用以显示本地化的状态描述或者自定义信息。

6. URL(统一资源定位符)

  • http:默认端口是80(可省略),https默认是443

  1. 超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中

    1. 传送协议

    2. 层级URL标记符号(为[//],固定不变)

    3. 访问资源需要的凭证信息(可省略)

    4. 服务器。(通常为域名,有时为IP地址)

    5. 端口号。(以数字方式表示,若为HTTP的默认值“:80”可省略)

    6. 路径。(以“/”字符区别路径中的每一个目录名称)

    7. 查询。(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)

    8. 片段。以“#”字符为起点,锚点(history模式)

     

  2. 浏览器发送请求和接收响应的过程?

    • HTTP/1.1默认是短暂的长链接,保持一个阈值时间

    1. 在浏览器中地址栏输入url,发送get请求

    2. 服务器接收到请求,获取url的路径,根据路径做不同操作,把返回的数据封装到响应体中,返回给浏览器

    3. 浏览器接收响应,双方断开链接

    4. 浏览器从响应体中获取数据,进行解析渲染

7. http请求和响应格式

  • 请求格式
浏览器 ——> 服务器

GET 请求没有请求数据

“请求方式 url路径 协议版本\r\n

k1:v1\r\n

k2:v2\r\n

\r\n

数据”
  • 响应格式
服务器 ——> 浏览器

“协议版本 状态码 状态码描述\r\n

k1:v1\r\n

k2:v2\r\n

\r\n

响应数据(响应体)”

 

1.3 web框架的功能

  1. socket收发消息(wsgiref(测试)、uwsgi(线上))

  2. 根据不同的路径返回不同内容

  3. 返回动态页面

  • Django:支持2和3;Flask:支持2(轻量级,其他功能需要其他模块);Tornado:支持1、2和3(异步非阻塞**)(同flask)

 

posted @ 2020-05-12 15:57  炜琴清  阅读(160)  评论(0)    收藏  举报