Web 应用基础¶
当我们用浏览器访问一个网站时,计算机在背后做了些什么?我们该如何搭建一个属于自己的网站?这里我们将讲授与 Web 以及构建 Web 应用有关的基础知识,让大家对网页的构成、当前互联网应用的架构与开发有初步的了解。
Acknowledgement:
引入¶
当我们访问网站的时候,发生了些什么?
关系
- Browser 浏览器 代表了使用者
- 访问网站时,一定有 Server 服务器 为你提供服务
步骤
- 浏览器通知服务器,自己需要某一路径的文件(某一型号的包裹)...
- 一些文件(包裹)从访问的服务器寄了回来...
- 浏览器收到这些包裹并拆开,将各个元件按照规则组装好...
- “包裹”里一般有哪些种类的文件呢?=> Web页面 (HTML CSS Javascript Debug_Page)
Web 页面¶
HTML¶
HTML (Hyper Text Markup Language, 超文本标记语言) 是一种用于描述网页文档的语言
- HTML 定义了许多不同种类的标签, 它们被尖括号包围,起始标签和结束标签通常成对出现
- 标签自身则表示了内容的类型与格式, 标签内含有具体的内容。例如,下面的代码表示加粗的“Hello World”
HTML | |
---|---|
1 |
|
Word 中,我们手动在 Tab 栏里调整格式,文本的写作、结构和格式的调整相分离
但是对于程序员而言,这种行为属于“文本”与“控制台”分开的行为,这种行为并不好,因此我们需要一种文本和控制相结合的模式
HTML 中,内容的格式信息也以标签的形式,作为 纯文本 存储在文件中,便于生成、编辑、传输、渲染
常用 HTML 标签
HTML | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Note
上述常见标签中,<br>
标签是空标签,即没有内容,仅仅起到换行的作用
它也是唯一可以单独使用的标签
作为“超文本标记语言”,HTML 标签还可以表征文本以外的内容:
- 图片、视频、超链接等 会显示在网页上的内容
- 标题、引入代码等 不会直接显示,但是它们与网页有关
常用 HTML 文本外的标签
HTML | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
举例:
HTML | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
生成效果:
HTML 标签属性
HTML 标签有很多属性,用来提供与标签有关的附加信息。属性总是以 名称/值 对的形式出现,比如:name="value"。
- id: 指定唯一标识
- class: 指定类名,可以与其他元素共享
- src: 源,用于链接外部资源,例如图片
- href: 超链接,用于链接到外部网页
- style: 指定样式
HTML | |
---|---|
1 2 |
|
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 |
|
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 |
|
效果:很显然此时“大标题”已经加红加粗了!
我们可以在文档头部添加 <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 |
|
JavaScript 是一种脚本语言,它不需要编译,嵌入 HTML 后随时可以解释运行
- 它是图灵完备的,可以实现任何逻辑;它的优势在于可以方便地访问网络、操纵 HTML 文档内的元素 (划重点!)
- 其语法在很多地方与 C++ 等语言类似,例如循环的写法,因此可以参考网上的教程自学(真的很简单)
- 和 CSS 文件一样,JavaScript 代码也可以被抽离至单独的文件中
语言的分类
除了编译语言和脚本语言,还有其他几种编程语言的分类方式。以下是几种常见的编程语言类别:
- 解释语言
- 特点:解释语言和脚本语言有相似之处,它们的代码由解释器逐行执行,不需要编译为机器代码。
- 例子:Python、Ruby、JavaScript(也是脚本语言)。
- 用途:用于快速开发和测试、Web开发、自动化任务等。
- 标记语言
- 特点:标记语言不是传统意义上的编程语言,它们主要用于描述和标记文档的结构和内容,而不是编写逻辑或算法。
- 例子:HTML、XML、Markdown。
- 用途:Web页面的结构描述、文档的格式化、数据表示。
- 函数式语言
- 特点:函数式编程语言基于数学函数的概念,强调函数的不可变性和无副作用,代码更易于测试和并行处理。
- 例子:Haskell、Lisp、Erlang。
- 用途:学术研究、并行计算、实时系统。
- 逻辑编程语言
- 特点:逻辑编程语言基于逻辑推理,通过给定的规则和事实进行推导和查询,程序的运行主要是通过逻辑关系来解决问题。
- 例子:Prolog、Datalog。
- 用途:人工智能、知识表示、自动推理。
- 面向对象语言
- 特点:面向对象语言支持面向对象编程(OOP)的概念,主要通过类和对象来组织代码,并支持封装、继承和多态等特性。
- 例子:Java、C++、Python(也支持面向对象编程)。
- 用途:软件开发、大型系统设计、游戏开发。
- 过程式语言
- 特点:过程式编程语言基于过程(或函数)的概念,程序被分解为一系列步骤或流程,主要通过函数调用来控制流程。
- 例子:C、Pascal、Fortran。
- 用途:系统编程、嵌入式开发、科学计算。
- 数据流语言
- 特点:数据流语言通过数据在网络中流动的概念来描述程序的执行过程,适用于并行处理和数据处理密集型的应用。
- 例子:LabVIEW、Verilog(用于硬件描述)。
- 用途:硬件设计、信号处理、并行计算。
- 声明式语言
- 特点:声明式编程语言通过描述“是什么”来编写程序,而不是“如何做”,注重问题的描述而不是操作的步骤。
- 例子:SQL、HTML(标记语言的一种)、Prolog(逻辑编程语言)。
- 用途:数据库查询、用户界面设计、规则推理。
- 并行/并发语言
- 特点:这些语言专门设计用于并行或并发执行任务,能够更好地利用多核处理器和分布式计算资源。
- 例子:Go、Erlang、Rust。
- 用途:高性能计算、实时系统、网络服务。
- 领域特定语言(DSL)
- 特点:领域特定语言是专门为特定应用领域设计的语言,通常语法简洁、针对性强。
- 例子:SQL(用于数据库查询)、R(用于统计计算)、MATLAB(用于数学和工程)。
- 用途:特定领域的专业应用,如数据库管理、数据分析、工程计算。
From ChatGPT :)
JavaScript 和 Java 没有任何关系,纯粹是发明者想要蹭热点🤡
例如:
效果很显然:
这里需要注意两个地方:
- 引入 CSS / JS 文件时的相对路径与绝对路径(很好理解)
<script>
标签的位置: 要在所有“任务”结束以后才可以(不然元素都没凑齐,咋渲染?)
Web 开发工具¶
- Google Chrome (大部分现代浏览器都采用了 Chromium 内核)
- F12 (Fn + F12)
- Ctrl/Command + S 保存网页
跟传统的调试工具一毛一样
Web 通信¶
过程
- 有时候,我们不仅希望请求一些文件;我们还需要主动发送一些信息,例如用户名、密码 ...
- 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
HTTP 调试¶
Debug 时,我们希望能向 任意地址(URL) 发送 __任意方法(GET/POST/PUT/DELETE)__的信息,携带任意正文...
推荐使用 Postman
Warning
如果你遇见多个可选择的网站,但凡有英文网站,就别用中文的(懂得都懂
进入“New Request”
You can make anything you want here!
Web 应用基础¶
静态网页¶
静态/动态网页
- 有些网站的内容是提前创建好、固定不变的,这些称为静态网页。例如 Hexo/Mkdocs/MkBook 等个人博客。
- 与之相对的是动态网页,网站内容会根据使用者的身份、后台数据库等因素动态生成,例如淘宝、京东。
- 对于静态网站,每一个地址对应的“包裹”里的内容是固定的;服务端不需要对内容做逻辑上的处理,只需要将已经打包好的包裹不断根据快递单寄出即可
Brief Intro
- 由于没有具体业务逻辑,一个通用的服务端软件即可满足需求,例如 Nginx
- 准备好 HTML, CSS, JS 文件,放在服务器指定路径上,让 Nginx 做一个支持发包的机器即可
- 网站就搭建好了🐶
Note
Nginx 是一个轻量级的 Web 服务器,它可以作为一个反向代理服务器,也可以作为一个负载均衡服务器,还可以作为一个网关服务器。
Nginx 功能非常强大,三言两语讲不完,我们将会另附专题进行讲解
动态网页¶
- 有些网页的内容不得不动态地变化...
- 内容需要实时更新,或者我们希望根据用户的身份显示不同的内容
(富有且慷慨😍)
前后端分离模式¶
传统模式
- 服务器在收到请求后,根据请求内容,从数据库中读取数据
- 将数据处理后填入预先准备好的模板当中,构成完整的HTML文件
- 将文件打包,作为包裹内容寄回
很显然这样的缺点太多了,我随便说几个:可扩展性太差/无效信息占用大量带宽...
因此我们提出“前后端分离模式”
- 对于绝大部分动态网页而言,“动态”的是具体的数据,网页的框架、呈现给用户的界面是“静态”的
- 把 “动态”数据填入“静态”模板 这一过程其实可以放到 客户端进行
- “前端”指的就是用户界面,“后端”指的就是数据与业务逻辑,两者可以完全分离
举个栗子🌰🐿️
Note
这就可以解释一个现象,在网速很慢的时候,你打开京东等网页,它们都只能显示出框架,但却并不能展示出商品图片
持久化存储¶
我们的数据该怎么保存呢?服务器重启,评测数据全部丢失?
Review
Memory是易失性存储,SSD是非易失性存储 🕶️
朴素想法:写到文件里去,下次启动的时候还在(这也需要一定的规范,例如之前提到的 JSON)
这就有点像格式规整的信息被存储到了" Word 文档" 里,事实上这并不方便
我们最希望的是类似于存到"Excel" 里面去!
这里不做过多介绍,可以翻阅笔者的k8s教程,其中有提到Storage部分,以及在数据库的课程CMU-15445和运维也都有提到,大家自行参考😄