提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:学习知识点:

这里主要记录学习 web App 入门,主要由两部分组成,第一部分是了解什么是 web App 以及什么是 Web框架,第二部分就是利用 Python 和 Python的一个Web框架(Django)搭建一个简单的网站。


一、Web App 是什么?

Web App (或 Web应用程序)运行于网络和标准的浏览器上,基于网页技术开服实现特定功能的应用。

前端:HTML ,CSS,JavaScript
后端:Java,Python,PHP
数据库:MySQL,Oracle,MongoDB
容器:Windows(IIS),Linux(Nginx,Apache)
协议:TCP,DNS,HTTP,HTTPS
在这里插入图片描述

1.当我们访问一个网站时发生了什么?

在这里插入图片描述
在这里插入图片描述

  • 客户输入URL,DNS解析URL得出IP地址,根据IP地址找出对应服务器
  • 客户机通过TCP/IP协议建立到Web服务器的TCP链接
  • 客户机向Web服务器发送HTTP请求报文,请求服务器里资源的资源文档
  • Web服务器接收到客户机的HTTP请求报文,然后向客户机发出HTTP响应报文
  • 如果请求的是HTML文档,web服务器会将对应目录下相应的HTML文档打开然后将文档的响应内容发送给客户机。
  • 如果请求的是PHP文件,那么web服务器自身是不能处理PHP动态语言脚本文件的,然后就会寻找并委托PHP应用服务器,PHP应用服务器会将Web服务器请求的PHP
  • 文件解析成HTML静态代码,然后将HTML静态代码发送给Web服务器,最后Web服务器会将HTML静态代码发送客户机。
  • 如果请求的资源是访问数据库,则Web服务器会通过PHP应用服务器去访问数据库
  • 客户机解析HTML静态文档
  • 客户机与服务器断开链接

2.常见的 Web 服务器有哪些?

Apache HTTP Server(简称Apache )是Apache软件基金会的一个开放源代码的网页服务器软件,可以在大多数电脑操作系统中运行,由于其跨平台和安全性被广泛使用,是最流行的Web服务器软件之一。

Nginx (发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS,SMTP, POP3,IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。

IIS是Internet Information Server的缩写。它是微软公司主推的服务器。

Lighttpd是一个德国人领导的开源Web服务器软件具有非常低的内存开销、CPU占用率低、效能好以及丰富的模块等特点。

Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。Tomcat技术先进、性能稳定,而且免费,因而深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。

二、Python 实现简单的 web服务器

1.编写 python 代码:

import threading
import time
from socket import *
from re import match


# s是否匹配 正则表达式rex
def like(s, rex):
    try:
        return s == match(rex, s).group()
    except:
        return False


# http请求
class Request:
    def __init__(self, sock: socket):
        self.sock = sock
        bys = b''
        s = 0
        while 1:
            if s == 4:
                break
            b = self.readOne()
            if b == None:
                break
            bys += b
            if s == 0 and b == b'\r':
                s += 1
            elif s == 1 and b == b'\n':
                s += 1
            elif s == 2 and b == b'\r':
                s += 1
            elif s == 3 and b == b'\n':
                s += 1
            else:
                s = 0
        # 获取请求头
        self.head = bys.decode()
        L = self.head.split("\r\n")
        U = L[1:-2]
        # 请求 方法
        self.method, self.uri, self.proto = L[0].split(" ")
        # 把请求头包装为字典
        self.map = {}
        for i in U:
            k, v = i.split(": ")
            self.map[k] = v

    # 读一个字节
    def readOne(self):
        b = self.sock.recv(1)
        if b == b'':
            return None
        return b


# http响应
class Response:
    def __init__(self, sock: socket, code="utf-8"):
        self.sock = sock
        self.head = ""
        self.status = 200
        self.code = code

    # 增加响应头
    def addHead(self, k, v):
        self.head += k + ": " + v + "\r\n"

    # 发送响应头
    def sendHead(self):
        h = "HTTP/1.1 " + str(self.status) + "\r\n" + self.head + "\r\n"
        self.sock.send(h.encode())

    # 响应字节流
    def write(self, bys):
        self.sock.send(bys)

    # 响应字符串
    def print(self, msg: str):
        self.sock.send(msg.encode(self.code))


class Server(socket):
    def __init__(self, ip="127.0.0.1", port=7000, lis=12) -> None:
        super().__init__(AF_INET, SOCK_STREAM)
        self.bind((ip, port))
        self.listen(lis)


# 服务器
class Servlet(Server):
    def __init__(self, ip="127.0.0.1", port=7000, lis=12) -> None:
        super().__init__(ip, port, lis)
        self.map = {}
        self.dir = {}
        self.code = "utf-8"

    # 增加响应方法
    def addFunction(self, urip, func):
        self.map[urip] = func

    # 增加静态资源根目录
    def addPageDir(self, uri, path):
        self.dir[uri] = path

    # 响应页面  path是本机的文件地址
    def ResPage(self, res: Response, path):
        file = open(path, "rb")
        res.sendHead()
        res.write(file.read())
        file.close()

    # 处理一个请求
    def Handle(self, sock: socket):
        req = Request(sock)
        res = Response(sock, self.code)
        uri = req.uri
        for k in self.map:
            if like(uri, k):
                func = self.map[k]
                func(req, res)
                sock.close()
                return
        for k in self.dir:
            v = self.dir[k]
            l = len(k)
            pre = uri[:l]
            print(k, pre)
            if k == pre:
                path = v + uri[l:]
                self.ResPage(res, path)
                sock.close()
                return

    # 启动
    def run(self):
        while 1:
            sock, _ = self.accept()
            th = threading.Thread(target=self.Handle, args=(sock,))
            th.start()

2.编写 html 代码:

代码如下(示例):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Hello Python</h1>
</body>
</html>

测试运行结果:

在这里插入图片描述
在这里插入图片描述


2.第二种方式:

代码如下(示例):

from http.server import BaseHTTPRequestHandler, HTTPServer


class RequestHandler(BaseHTTPRequestHandler):

    # ...页面模板...
    Page = '''\
	<html>
	<body>
	<table>
	<tr>  <td>Hello</td>         <td>World</td>          </tr> 
	</table>
	</body>
	</html>
	'''

    def do_GET(self):
        print("GET request Path:",str(self.path) ,"\r\nHeaders:\r\n", str(self.headers))
        page = self.create_page()
        self.send_content(page)

    def create_page(self):
        values = {
            'date_time': self.date_time_string(),
            'client_host': self.client_address[0],
            'client_port': self.client_address[1],
            'command': self.command,
            'path': self.path
        }
        page = self.Page.format(**values)
        return page

    def send_content(self, page):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-Length", str(len(page)))
        self.end_headers()
        self.wfile.write(page.encode('utf-8'))


if __name__ == '__main__':
    serverAddress = ('', 8080)
    server = HTTPServer(serverAddress, RequestHandler)
    server.serve_forever()

这个时候直接访问:
在这里插入图片描述
python server 输出:

EDGE 浏览器返回:

GET request Path: /favicon.ico 
Headers:
 Host: 127.0.0.1:8080
Connection: keep-alive
sec-ch-ua: " Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44
sec-ch-ua-platform: "Windows"
Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://127.0.0.1:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

IE 浏览器访问返回:

127.0.0.1 - - [07/Jul/2022 21:39:18] "GET / HTTP/1.1" 200 -
GET request Path: / 
Headers:
 Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.2
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: 127.0.0.1:8080
Connection: Keep-Alive

可以看到User-Agent 之间的区别

三、什么是框架

  • Web应用框架(Web application framework)是一种开发框架,用来支持动态网站、网络应用程序及网络服务的开发。其类型有基于请求的和基于组件的两种框架
  • 有助于减轻网页开发时共通性活动的工作负荷,例如许多框架提供数据库访问接口、标准样板以及会话管理等,可提升代码的可再用性

总结

这里简单罗列一些常用的 Web 框架
在这里插入图片描述

JQuery  Booststrap React.js Vue ...

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐