跳转至

Web 应用基础

当我们用浏览器访问一个网站时,计算机在背后做了些什么?我们该如何搭建一个属于自己的网站?这里我们将讲授与 Web 以及构建 Web 应用有关的基础知识,让大家对网页的构成、当前互联网应用的架构与开发有初步的了解。

Acknowledgement:

  1. 清华大学酒井科协暑期培训资料
  2. Google 开发者文档
  3. Mozilla 培训文档

引入

当我们访问网站的时候,发生了些什么?

关系

  • Browser 浏览器 代表了使用者
  • 访问网站时,一定有 Server 服务器 为你提供服务

步骤

  1. 浏览器通知服务器,自己需要某一路径的文件(某一型号的包裹)...
  2. 一些文件(包裹)从访问的服务器寄了回来...
  3. 浏览器收到这些包裹并拆开,将各个元件按照规则组装好...
  4. “包裹”里一般有哪些种类的文件呢?=> Web页面 (HTML CSS Javascript Debug_Page)

Web 页面

HTML

HTML (Hyper Text Markup Language, 超文本标记语言) 是一种用于描述网页文档的语言

  • HTML 定义了许多不同种类的标签, 它们被尖括号包围,起始标签和结束标签通常成对出现
  • 标签自身则表示了内容的类型与格式, 标签内含有具体的内容。例如,下面的代码表示加粗的“Hello World”
HTML
1
<b> Hello World </b>

Word 中,我们手动在 Tab 栏里调整格式,文本的写作、结构和格式的调整相分离

alt text

但是对于程序员而言,这种行为属于“文本”与“控制台”分开的行为,这种行为并不好,因此我们需要一种文本和控制相结合的模式

HTML 中,内容的格式信息也以标签的形式,作为 纯文本 存储在文件中,便于生成、编辑、传输、渲染

常用 HTML 标签

HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<h1> ~ <h6> 定义标题,从最高级别到最低级别
<p> 定义段落
<ul> 定义无序列表
<ol> 定义有序列表
<li> 定义列表项
<table> 定义表格
<tr> 定义表格的行
<td> 定义表格的单元格
<th> 定义表格的表头单元格
<strong> 定义强调的文本
<em> 定义斜体的文本
<br> 插入换行符
Note

上述常见标签中,<br> 标签是空标签,即没有内容,仅仅起到换行的作用

它也是唯一可以单独使用的标签

作为“超文本标记语言”,HTML 标签还可以表征文本以外的内容:

  • 图片、视频、超链接等 会显示在网页上的内容
  • 标题、引入代码等 不会直接显示,但是它们与网页有关

常用 HTML 文本外的标签

HTML
1
2
3
4
5
6
7
8
9
<html> 定义 HTML 文档的根元素
<head> 定义文档的头部区域
<body> 定义文档的主体区域
<img> 插入图像
<a> 创建链接
<div> 定义一个区块或容器
<span> 标记或包装文本片段
<header> 定义页眉部分
<style> 定义内部样式表

举例:

HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>
<!--声明文档类型-->
<html>
<head>
    <title>Tab 栏标题 </title>
</head>
<body>
    <h1> 大标题 </h1>
    <p> 一个段落 <b> 加粗了一些内容 </b></p>
    <HR>
    <!-- 横线一条 -->
    <img src="./image/0-1.png">
    <!--一张图片-->
</body>
</html>

生成效果:

alt text

HTML 标签属性

HTML 标签有很多属性,用来提供与标签有关的附加信息。属性总是以 名称/值 对的形式出现,比如:name="value"。

  • id: 指定唯一标识
  • class: 指定类名,可以与其他元素共享
  • src: 源,用于链接外部资源,例如图片
  • href: 超链接,用于链接到外部网页
  • style: 指定样式
HTML
1
2
<img src="./image/0-1.png" width="200" height="200">
<div id="main" class="cont" style="color: red;">

DIV 标签

相信细心的你已经发现了,上述的内容都是默认竖向叠加的,那么我希望元素横向排列该如何做?

  • <div> 标签可以在网页中创建一个无语义的块级容器,可以用来分组、包含、布局和样式化其他 HTML 元素。
  • <div> 标签没有特定的含义或目的,它只是一个容器。

思路:新建一个 div ,将其内部元素的排列方向设为水平;将需要左右排列的元素置于该 div 内部

例如:

HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- 指定文档使用的字符编码为UTF-8,确保在所有设备上都能正确显示文本 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 设置视口的宽度与设备的宽度一致,确保在移动设备上有良好的显示效果 -->
    <title>Horizontal Layout Example</title>
    <!-- 设置网页标题,在浏览器标签中显示 -->
    <style>
        .container {
            display: flex; /* 使子元素水平排列 */
            justify-content: space-between; /* 子元素之间的间距被均匀分配 */
            padding: 10px; /* 在容器内边缘添加10px的内边距 */
            border: 1px solid #ccc; /* 为容器添加1px的灰色边框 */
        }
        .item {
            padding: 20px; /* 在每个子元素的内部添加20px的内边距 */
            background-color: #f0f0f0; /* 设置每个子元素的背景颜色为浅灰色 */
            border: 1px solid #ddd; /* 为每个子元素添加1px的浅灰色边框 */
        }
    </style>
</head>
<body>

<div class="container">
    <div class="item">Item 1</div> <!-- 第一个子元素,显示文本"Item 1",有背景色、内边距和边框 -->
    <div class="item">Item 2</div> <!-- 第二个子元素,显示文本"Item 2",有背景色、内边距和边框 -->
    <div class="item">Item 3</div> <!-- 第三个子元素,显示文本"Item 3",有背景色、内边距和边框 -->
</div>

</body>
</html>

alt text

CSS & JS

  • 现在的网站似乎有些朴素 🤡
  • 可以在标签内添加 style="..." 属性,进行美化
  • 也可以在文档头部添加 <style> 标签,在其中定义不同类型的标签的格式,进行批量调整

例如

HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<!--声明文档类型-->
<html>
<head>
    <title>Tab 栏标题 </title>
    <style>
        h1 {
            color: red;
            font-weight: bold;
        }
    </style>
    <!--人为定义了 h1 标签的颜色和字体-->
</head>

<body>
    <h1> 大标题 </h1>
    <p> 一个段落 <b> 加粗了一些内容 </b></p>
    <HR>
    <!-- 横线一条 -->
    <img src="./image/0-1.png">
    <!--一张图片-->
</body>
</html>

效果:很显然此时“大标题”已经加红加粗了!

alt text

我们可以在文档头部添加 <style> 标签,在其中定义不同格式的标签,他们控制着网页的外观、颜色、布局、动画效果

  • 同一网站不同页面的格式往往是统一的,因此这些样式可以被抽离出来,成为 CSS (Cascading Style Sheets) 文件
  • 除了元素类型,CSS 还可以根据元素的类、id 进行选择
  • 之所以叫做“层叠样式表”,是因为当有多个规则作用于同一个元素时,规则会按照一定顺序叠加

JavaScript

  • 在点击一个图标后,我希望网页的内容发生一些变化(动态了!)
  • 可以通过一种“简易”的脚本语言来达到这一目的
JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<!--声明文档类型-->
<html>
<head>
    <title>Tab 栏标题 </title>
    <style>
        h1 {
            color: red;
            font-weight: bold;
        }
    </style>
    <!--人为定义了 h1 标签的颜色和字体-->
</head>

<body>
    <h1> 大标题 </h1>
    <p> 一个段落 <b> 加粗了一些内容 </b></p>
    <HR>
    <!-- 横线一条 -->
    <img src="./image/0-1.png" onclick="let x = 'I need girlfriend :('; alert(x);">
    <!--一张图片-->
</body>
</html>

alt text

JavaScript 是一种脚本语言,它不需要编译,嵌入 HTML 后随时可以解释运行

  • 它是图灵完备的,可以实现任何逻辑;它的优势在于可以方便地访问网络、操纵 HTML 文档内的元素 (划重点!)
  • 其语法在很多地方与 C++ 等语言类似,例如循环的写法,因此可以参考网上的教程自学(真的很简单)
  • 和 CSS 文件一样,JavaScript 代码也可以被抽离至单独的文件中
语言的分类

除了编译语言和脚本语言,还有其他几种编程语言的分类方式。以下是几种常见的编程语言类别:

  1. 解释语言
    • 特点:解释语言和脚本语言有相似之处,它们的代码由解释器逐行执行,不需要编译为机器代码。
    • 例子:Python、Ruby、JavaScript(也是脚本语言)。
    • 用途:用于快速开发和测试、Web开发、自动化任务等。
  2. 标记语言
    • 特点:标记语言不是传统意义上的编程语言,它们主要用于描述和标记文档的结构和内容,而不是编写逻辑或算法。
    • 例子:HTML、XML、Markdown。
    • 用途:Web页面的结构描述、文档的格式化、数据表示。
  3. 函数式语言
    • 特点:函数式编程语言基于数学函数的概念,强调函数的不可变性和无副作用,代码更易于测试和并行处理。
    • 例子:Haskell、Lisp、Erlang。
    • 用途:学术研究、并行计算、实时系统。
  4. 逻辑编程语言
    • 特点:逻辑编程语言基于逻辑推理,通过给定的规则和事实进行推导和查询,程序的运行主要是通过逻辑关系来解决问题。
    • 例子:Prolog、Datalog。
    • 用途:人工智能、知识表示、自动推理。
  5. 面向对象语言
    • 特点:面向对象语言支持面向对象编程(OOP)的概念,主要通过类和对象来组织代码,并支持封装、继承和多态等特性。
    • 例子:Java、C++、Python(也支持面向对象编程)。
    • 用途:软件开发、大型系统设计、游戏开发。
  6. 过程式语言
    • 特点:过程式编程语言基于过程(或函数)的概念,程序被分解为一系列步骤或流程,主要通过函数调用来控制流程。
    • 例子:C、Pascal、Fortran。
    • 用途:系统编程、嵌入式开发、科学计算。
  7. 数据流语言
    • 特点:数据流语言通过数据在网络中流动的概念来描述程序的执行过程,适用于并行处理和数据处理密集型的应用。
    • 例子:LabVIEW、Verilog(用于硬件描述)。
    • 用途:硬件设计、信号处理、并行计算。
  8. 声明式语言
    • 特点:声明式编程语言通过描述“是什么”来编写程序,而不是“如何做”,注重问题的描述而不是操作的步骤。
    • 例子:SQL、HTML(标记语言的一种)、Prolog(逻辑编程语言)。
    • 用途:数据库查询、用户界面设计、规则推理。
  9. 并行/并发语言
    • 特点:这些语言专门设计用于并行或并发执行任务,能够更好地利用多核处理器和分布式计算资源。
    • 例子:Go、Erlang、Rust。
    • 用途:高性能计算、实时系统、网络服务。
  10. 领域特定语言(DSL)
    • 特点:领域特定语言是专门为特定应用领域设计的语言,通常语法简洁、针对性强。
    • 例子:SQL(用于数据库查询)、R(用于统计计算)、MATLAB(用于数学和工程)。
    • 用途:特定领域的专业应用,如数据库管理、数据分析、工程计算。

From ChatGPT :)

JavaScript 和 Java 没有任何关系,纯粹是发明者想要蹭热点🤡

例如:

alt text

效果很显然:

alt text

这里需要注意两个地方:

  • 引入 CSS / JS 文件时的相对路径与绝对路径(很好理解)
  • <script> 标签的位置: 要在所有“任务”结束以后才可以(不然元素都没凑齐,咋渲染?)

Web 开发工具

  • Google Chrome (大部分现代浏览器都采用了 Chromium 内核)
  • F12 (Fn + F12)
  • Ctrl/Command + S 保存网页

alt text

跟传统的调试工具一毛一样

Web 通信

alt text

过程

  • 有时候,我们不仅希望请求一些文件;我们还需要主动发送一些信息,例如用户名、密码 ...
  • HTTP (Hyper Text Transfer Protocol) 规定了沟通的格式
  • 每一次沟通都由客户端发起,发送一个 request,请求正文中可以携带各种信息
  • 服务器收到请求后,会返回一个 response,正文中也可以带有 HTML 等(任意格式的)文件

HTTP request

请求从客户端发送 至服务端。不同的请求方法具有不同的语义:

  • GET: 请求指定的资源
  • POST: 提交数据
  • PUT: 用提交的数据更新或替换指定资源
  • DELETE: 删除服务器端指定的资源

根据上述知道了有不同的请求方法,那么该怎么携带具体信息呢?

  • 路径传参, 例如用 GET 方法请求 http://IneedGirlFriend.com/score/2022010897/
  • Query String, 例如用 GET 方法请求 http://IneedGirlFriend.com/score?semester=24fall&GPA=4.0&Look=Handsome
  • 请求体传参,我们可以在请求的正文中传输任意格式的信息作为参数,例如 POST 请求 http://IneedGirlFriend.com/score 并携带以下 JSON 格式的信息
    JSON
    1
    2
    3
    4
    5
    {
    "id": 2022010897,
    "semester": "23fall",
    "GPA": 4.0
    }
    
JSON

JSON 是一种很常见的数据交换格式,也很好学,自行GPT学一通得了

HTTP response

服务器收到客户端发来的请求后,会进行处理,并返回一个response。

response 没有不同的分类,但是有不同的状态码,表示不同的响应结果:

  • 200 OK: 请求成功
  • 400 Bad Request: 请求有误
  • 404 Not Found: 请求的资源不存在(这个想必宅男很清楚🐶)
  • 500 Internal Server Error: 服务器内部错误

HTTP response 的正文中可以携带 HTML 文档、JSON 数据、图片等任何内容

summary

alt text

alt text

HTTP 调试

Debug 时,我们希望能向 任意地址(URL) 发送 __任意方法(GET/POST/PUT/DELETE)__的信息,携带任意正文...

推荐使用 Postman

Warning

如果你遇见多个可选择的网站,但凡有英文网站,就别用中文的(懂得都懂

alt text

进入“New Request”

alt text

You can make anything you want here!

Web 应用基础

静态网页

静态/动态网页

  • 有些网站的内容是提前创建好、固定不变的,这些称为静态网页。例如 Hexo/Mkdocs/MkBook 等个人博客。
  • 与之相对的是动态网页,网站内容会根据使用者的身份、后台数据库等因素动态生成,例如淘宝、京东。
  • 对于静态网站,每一个地址对应的“包裹”里的内容是固定的;服务端不需要对内容做逻辑上的处理,只需要将已经打包好的包裹不断根据快递单寄出即可

Brief Intro

  • 由于没有具体业务逻辑,一个通用的服务端软件即可满足需求,例如 Nginx
  • 准备好 HTML, CSS, JS 文件,放在服务器指定路径上,让 Nginx 做一个支持发包的机器即可
  • 网站就搭建好了🐶
Note

Nginx 是一个轻量级的 Web 服务器,它可以作为一个反向代理服务器,也可以作为一个负载均衡服务器,还可以作为一个网关服务器。

Nginx 功能非常强大,三言两语讲不完,我们将会另附专题进行讲解

动态网页

  1. 有些网页的内容不得不动态地变化...
  2. 内容需要实时更新,或者我们希望根据用户的身份显示不同的内容

alt text

(富有且慷慨😍)

前后端分离模式

传统模式

  1. 服务器在收到请求后,根据请求内容,从数据库中读取数据
  2. 将数据处理后填入预先准备好的模板当中,构成完整的HTML文件
  3. 将文件打包,作为包裹内容寄回

很显然这样的缺点太多了,我随便说几个:可扩展性太差/无效信息占用大量带宽...

因此我们提出“前后端分离模式”

  1. 对于绝大部分动态网页而言,“动态”的是具体的数据,网页的框架、呈现给用户的界面是“静态”的
  2. “动态”数据填入“静态”模板 这一过程其实可以放到 客户端进行
  3. “前端”指的就是用户界面,“后端”指的就是数据与业务逻辑,两者可以完全分离

alt text

举个栗子🌰🐿️

alt text

alt text

Note

这就可以解释一个现象,在网速很慢的时候,你打开京东等网页,它们都只能显示出框架,但却并不能展示出商品图片

alt text

持久化存储

我们的数据该怎么保存呢?服务器重启,评测数据全部丢失?

Review

Memory是易失性存储,SSD是非易失性存储 🕶️

朴素想法:写到文件里去,下次启动的时候还在(这也需要一定的规范,例如之前提到的 JSON)

这就有点像格式规整的信息被存储到了" Word 文档" 里,事实上这并不方便

我们最希望的是类似于存到"Excel" 里面去!

这里不做过多介绍,可以翻阅笔者的k8s教程,其中有提到Storage部分,以及在数据库的课程CMU-15445和运维也都有提到,大家自行参考😄