JV-01 Web基础
01 · Web 基础(Web Basics)
📅 预计 45 分钟 | ⭐ = 高频考点 | 📌 中英术语见文末
✍️ 配套练习:网页 quizshengxia.dev/java?module=01
1.1 Web 是什么与工作原理
像逛菜市场:你问价,摊位给货
把 Web(万维网)想成菜市场:你走到摊位前问"今天有什么菜"(发出请求),摊位老板把菜摆给你看(返回响应)。菜市场能天天开张,靠的是"顾客—摊位"这个稳定分工;Web 能天天运转,靠的是"客户端—服务器"这套固定配合。你每刷一次网页、每点一次链接,本质上都在重复这个"问价—给货"的循环,只是速度快到你几乎感觉不到。
Web 全称是万维网(World Wide Web),它是运行在互联网之上的服务,而不是互联网本身。互联网是连接全世界电脑的物理"路网"(光纤、网线、路由器组成的传输网络),Web 只是跑在这条路上的一种"快递服务"。除了 Web,电子邮件(Email)、文件传输(FTP)、远程登录(SSH)也都是跑在互联网上的服务。理解这一层,你就不会把"上不了网"和"网站打不开"混为一谈:前者是路断了,后者可能是路上这家店关了。
Web 由三个核心部分组成:
| 组件 | 英文 | 作用 | 生活类比 |
|---|---|---|---|
| 网页 | Web Page | 你看到的内容 | 摊位上的菜 |
| 网址 | URL | 找到内容的地址 | 摊位的门牌号 |
| 浏览器 | Browser | 帮你取内容的工具 | 你的腿 |
Web 的工作原理:一问一答
Web 的所有操作都可以概括为四个字:请求、响应(request / response)。浏览器主动向服务器要东西,服务器被动把东西还回来。这种"主动方永远是浏览器、被动方永远是服务器"的关系不会互换,就像菜市场里永远是顾客开口问价,摊位老板不会追着你推销。
用 Java 伪代码描述这个"问答循环",你会发现核心逻辑其实很简单:
// 伪代码:Web 世界的本质就是一个"问答循环"
while (服务器在运行) {
请求 req = 接收请求(); // 浏览器说"我要 xxx"
内容 out = 找答案(req); // 找现成文件,或让程序现算
返回响应(out); // 把网页端到浏览器面前
}
服务器找答案有两种方式:要么直接读磁盘上写死的文件(静态网页),要么运行一段程序现场生成(动态网页)。这两种方式我们在 1.6 节详细对比,你现在只要记住"回答之前必须先收到问题"就够了。
💡 记忆口诀:Web = 一问一答。浏览器永远是"问"的一方,服务器永远是"答"的一方,角色不能互换。
⚠️ 常见错误
- 把 Web 和互联网混为一谈:互联网是物理网络,Web 只是跑在它上面的众多服务之一。为什么容易混?因为 90% 的人上网只用浏览器,误以为"联网 = 逛网页"。怎么避免?记住 Email、FTP 也是互联网服务,它们和 Web 是并列关系。
- 以为请求只能由浏览器发起:curl 命令、爬虫程序、手机 App、小程序都能发 HTTP 请求,浏览器只是最常用的客户端。为什么重要?调试接口时你经常用 curl 模拟请求,不会这个手段会很被动。
- 认为服务器一定是一台电脑:服务器可以是多台机器组成的集群,也可以一台机器上跑多个"虚拟服务器"。"服务器"本质是"提供服务的程序",不是一个具体的铁盒子。面试里问"一台服务器能同时部署几个网站"时,答案就是"无数个,只要端口和域名能区分"。
1.2 客户端-服务器架构
饭店:顾客点菜,后厨做菜
客户端-服务器架构(Client-Server Architecture)就像一家饭店:你(客户端)拿着菜单点菜,后厨(服务器)做完端上来。顾客不关心后厨怎么切菜、用什么锅;后厨也不关心你坐哪一桌、穿什么衣服。两边只通过"菜单—上菜"这个约定好的接口打交道,互不越界。这种"分工明确、接口稳定"的架构,让 Web 能支撑几十亿用户同时使用。
- 客户端(Client):发起请求的一方,典型代表是浏览器。它负责两件事:把网页渲染成你能看懂的界面,以及把你的操作(点按钮、输表单、划页面)翻译成一个 HTTP 请求。
- 服务器(Server):保存和处理资源的一方。它 24 小时开机、有固定地址(IP),负责存网页、存图片、跑程序、连数据库。服务器一旦宕机,所有依赖它的客户端都会"点菜没人做"。
| 维度 | 客户端 | 服务器 |
|---|---|---|
| 角色 | 主动请求 | 被动响应 |
| 典型代表 | 浏览器、手机 App | Tomcat、Nginx、Apache |
| 资源 | 几乎不保存业务数据 | 网页、图片、数据库的大本营 |
| 状态 | 想关就关 | 常年在线,宕机业务就停 |
客户端负责"显示",服务器负责"算和存"
分工的核心一句话:客户端不保存真正的资源,服务器才是资源的大本营。你刷淘宝,商品图片、库存、价格、你的购物车,全部存在淘宝的服务器和数据库里;你本地的浏览器只保存了一份"看过的副本"(缓存)。所以哪怕你把浏览器缓存清空、换个新电脑、甚至把手机格式化,数据一样不少——只要服务器还在,数据就在。
这也解释了为什么 Web 开发的核心在"服务端":权限校验、数据计算、安全防护都发生在服务器上。客户端做得再漂亮,也只是"一张嘴";服务器才是"食材和手艺"。这就是为什么要花大力气学 Servlet、学数据库、学部署——都是"后厨"的功夫。
💡 记忆口诀:客户端是"前台",服务器是"仓库+后厨"。前台只管递单上菜,仓库后厨才管存货做菜。丢数据先找服务器,别急着怪自己浏览器。
⚠️ 常见错误
- 把"换设备数据还在"归功于浏览器:很多人以为"我登录过的网站换个电脑还在"是浏览器厉害。其实数据都在服务器,浏览器只是在你登录后拿了一张"临时通行证"(Cookie)。这个认知错误会让你在后端开发时忘记"状态存哪里"。
- 以为服务器必须是一台高性能电脑:初学者总把服务器想象成机房里的高端机器。开发阶段你本机跑一个 Tomcat 就是服务器,性能不重要,重要的是"职责"——它在扮演提供资源的角色。
- 忽略客户端可能不诚实:初学者常假设"浏览器发的请求都是真的"。但客户端完全可控,攻击者可以伪造请求、篡改参数。所以服务器必须自己校验数据,绝不能相信客户端传过来的任何值——这是后文安全设计的基本立场。
1.3 URL 结构分解 ⭐
快递单:地址拆成五段
寄快递要写清"省 / 市 / 区 / 街道 / 门牌号",缺一段都可能送错。URL(统一资源定位符)就是 Web 世界的快递单,地址被拆成几段,每一段都有明确含义、缺一不可。看这个标准例子:
https://www.example.com:8080/path/to/page?name=tom&age=20
| 组成 | 例子 | 作用 |
|---|---|---|
| 协议 | https |
用什么规则访问 |
| 主机名 | www.example.com |
哪台服务器 |
| 端口 | 8080 |
服务器上的哪个"门" |
| 路径 | /path/to/page |
哪个资源 |
| 查询参数 | name=tom&age=20 |
捎给服务器的附加信息 |
每一段都要背清楚
- 协议(protocol):最常见的两个是
http和https。https 多一个 s,表示"安全版"(在 HTTP 外面套了一层加密)。协议必须和服务器配置匹配,否则连不上。 - 主机名(host):给人看的域名,本质是"好记的名字"。机器之间真正通信靠 IP 地址,域名只是通过 DNS 翻译成 IP 的别名。
- 端口(port):一台服务器上可以开很多服务(网页服务、邮件服务、数据库服务),端口就是区分这些服务的"门牌号"。HTTP 默认 80,HTTPS 默认 443;浏览器里不写端口号时,会自动补默认值。
- 路径(path):资源在服务器上的存放位置,如
/index.html、/user/login。注意它和服务器磁盘路径不是一回事,是"虚拟路径",由服务器程序决定怎么映射。 - 查询参数(query):
?后面跟着的键值对,多个用&连接,用来捎带附加信息(如搜索关键词、页码)。参数到#为止,#后面是网页内部的"锚点"(定位到页面某个位置),根本不会发给服务器。
用 Java 伪代码拆开这个 URL,体会每一段的含义:
// 伪代码:拆 URL 看结构(真实解析更复杂,这里只看各部分含义)
String url = "https://www.example.com:8080/path/to/page?name=tom&age=20";
String protocol = url.substring(0, 8); // "https://" 用什么规则
String host = url.substring(8, 25); // "www.example.com" 去哪台机器
String port = url.substring(25, 29); // "8080" 敲哪个门
String path = url.substring(29, 44); // "/path/to/page" 要哪个资源
String query = url.substring(45); // "name=tom&age=20" 捎带的附加信息
System.out.println("协议=" + protocol);
System.out.println("主机=" + host + " 端口=" + port);
// 输出:协议=https:// 主机=www.example.com 端口=8080
💡 记忆口诀:拆 URL 从右往左读——
?分参数、#是锚点、/分段、:后是端口、//后是主机、最前是协议。
⚠️ 常见错误
- 协议写错导致无法访问:服务器只开了 443 端口时,你用
http://访问会连接失败或被强制跳转。为什么?443 端口根本没有明文服务在监听。怎么避免?先确认网站给的是 http 还是 https,再决定地址栏怎么写。 - 忘记端口号的作用:
localhost:8080和localhost:80可能是两个完全不同的服务。初学者经常"在 8080 起的服务却用 80 去访问",结果一直连不上。怎么避免?启动服务时看控制台输出的端口,访问时带上它。 - 查询参数分隔符写错:第一个参数前用
?,后面的用&。写成?name=tom?age=20,第二个?会被当成参数名的一部分,服务器取age时得到null。这是排查"参数丢失"时最先该看的地方。 - URL 里出现裸空格:URL 不允许裸空格,空格要编码成
%20。name=to m会解析失败或截断。为什么?空格在 URL 里有特殊含义(分隔符),必须转义。前端开发时用encodeURIComponent()处理参数就能避免。
1.4 HTTP 请求-响应模型概览 ⭐
点外卖:下单一句话,收货一张票
HTTP(超文本传输协议)是 Web 的"对话规则",规定了两边怎么开口、怎么接话、怎么结束。点外卖时你下单一句话"一份黄焖鸡,微辣",商家做好后给你一张取餐票;HTTP 世界里,请求(request)和响应(response)就是这两张纸,一张是你说的话,一张是商家的回执。
一个 HTTP 请求的原始报文长这样(第 02 讲会逐行拆解,这里先混个眼熟):
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
一个 HTTP 响应的原始报文长这样:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<html><body>你好,Web 世界!</body></html>
核心要点:请求里说明"想要什么(路径)、给谁(Host)、怎么给(方法)";响应里说明"成没成功(状态码)、什么类型(Content-Type)、内容是什么(主体)"。两边都用纯文本沟通,这正是 HTTP 好调试的原因——抓包工具里看到的都是人眼能读懂的字符,而不是乱码。
💡 记忆口诀:HTTP = 一问一答的纯文本对话。请求"提要求",响应"给结果"。看到请求先看方法,看到响应先看状态码。
DNS:分拣中心帮你查门牌号
机器之间通信用的是 IP 地址(如 93.184.216.34),但人类记不住这一串数字,于是有了域名。DNS(域名系统) 就是把这个映射关系管起来的全球"电话簿":你给它一个域名,它告诉你对应的 IP。整个过程在毫秒级完成,你几乎感知不到。
你输入 www.example.com
↓ 问:这个域名对应哪个 IP?
DNS 服务器翻电话簿 → 答:93.184.216.34
你的电脑拿着这个 IP 去建立连接
DNS 的一个特点值得记住:它有多级缓存。你的电脑、路由器、本地运营商都缓存了最近查过的记录,所以同一个域名不会每次都问"总电话簿"。这也是为什么改完网站域名解析后要等一段时间才生效——因为沿途缓存的旧记录还没过期。
💡 记忆口诀:DNS = 域名查 IP 的电话簿。浏览器记不住 IP,就像你记不住朋友的手机号,通讯录帮你查,而且沿途各级都有备份。
1.5 一次完整请求的旅程
从"敲回车"到"看到页面"的六步
把一次访问当成寄一封信给远方的朋友:你写下地址(输入网址)、邮局查门牌(DNS 解析)、打车过去(TCP 建立连接)、递上信(发送请求)、朋友回信(服务器响应)、你读信(浏览器渲染)。这六步环环相扣,任何一步断了,页面都出不来。
① 输入网址 在地址栏敲下 https://www.example.com
② DNS 解析 查出 IP:93.184.216.34
③ TCP 连接 三次握手,确认通话就绪
④ 发送请求 浏览器说:我要 GET /index.html
⑤ 服务器处理 返回 200 + 网页内容
⑥ 浏览器渲染 解析 HTML/CSS/JS,画出你看到的页面
每一步都可能出问题:DNS 挂了打不开(②)、服务器宕机连不上(③⑤)、404 是资源不存在(⑤)。排错时顺着这条链一步步排查,是后端开发的基本功:先看能不能解析域名(ping 或 nslookup),再看端口通不通(telnet),最后看服务器日志——这样能快速把问题范围缩小到"网络层还是应用层"。
// 伪代码:服务器处理一次请求的简化流程
void 处理(请求 req, 响应 resp) {
String 路径 = req.getPath(); // 客户要什么
if ("/index.html".equals(路径)) {
resp.setStatus(200); // 找到了
resp.write("网页内容");
} else if ("/login".equals(路径)) {
resp.setStatus(200); // 动态生成
resp.write("这是登录页,由程序现场生成");
} else {
resp.setStatus(404); // 没找到
resp.write("页面不存在");
}
}
一问一答,答完就散
一个请求对应一个响应,而且默认"无状态":服务器处理完一个请求就"失忆"了,不记得你上次来要过什么。就像快餐店排队——你上回点了什么,店员这次完全不知道,每次都从头来。这一特性是 HTTP 协议设计的初衷:简单、省资源、扛得住海量并发。
但"无状态"也带来了问题:购物车怎么记住?登录状态怎么保持?答案是 Cookie 和 Session(第 02 讲、后续章节会讲)。你只要先记住这个基本模型:默认无记忆,想要记忆得自己加机制。
💡 记忆口诀:一问一答,答完就散。想记住上次的状态?那是 Cookie / Session 的事,基础模型本身"无记忆"。
1.6 静态网页与动态网页 + Web 容器
打印店:现成海报 vs 现做海报
静态网页(static)像打印店货架上的现成海报:印好了放在那,谁来都拿同一张,速度快、成本低。动态网页(dynamic)像定制海报:老板根据你给的信息(名字、日期、照片)现场排版打印,每个人拿到的都可能不同。淘宝的搜索结果页、你的个人订单页,都是动态网页——内容取决于"你是谁、你搜了什么"。
| 对比 | 静态网页 | 动态网页 |
|---|---|---|
| 内容 | 写死存在文件里 | 运行时计算 / 查数据库生成 |
| 例子 | index.html |
淘宝商品页、订单页 |
| 谁生成 | 服务器直接返回文件 | 程序(Java/PHP/Python)现算 |
| 优点 | 快、省资源 | 内容可变、千人千面 |
| 缺点 | 内容一成不变 | 慢一些、依赖服务器算力 |
动态网页的"现场做"靠的是服务器上的程序。要让 Java 程序能处理 HTTP 请求、动态生成 HTML,就需要一个"翻译官 + 管家"——这就是 Web 容器。
Web 容器:Servlet 的房东和管家
Web 容器(Web Container),最经典的是 Tomcat,它把"接待客人"的杂活全包了,只留"怎么招待"给你写。具体做三件事:
- 监听端口、解析 HTTP:浏览器发来的原始 HTTP 报文它替你拆开,变成一个个 Java 对象,你不用碰字符串。
- 管理 Servlet 生命周期:Servlet 是你写的处理请求的 Java 类(第 03 讲),容器负责"什么时候创建、什么时候调用、什么时候销毁"。
- 处理并发:多个用户同时访问,容器自动为每个请求分配一个线程,你不用手写线程池。
没有容器时这些活全要你自己干,感受一下:
// 伪代码:没有容器时你要自己干的活
ServerSocket 端口 = new ServerSocket(8080); // ① 自己监听端口
Socket 连接 = 端口.accept(); // ② 自己等客人上门
String 原始报文 = 读入(连接); // ③ 自己读原始 HTTP 文本
String 路径 = 手动解析(原始报文); // ④ 自己拆 URL、拆请求头
String 参数 = 手动取参数(原始报文); // ⑤ 自己解析表单数据
// ...还要自己管多线程、自己处理异常、自己区分静态和动态
有了 Tomcat,你只需写一个类、配一个映射,剩下的"接待流程"全部交给容器。这也是为什么真实项目里没有人从头写一个 Web 服务器——造轮子不划算,轮子早有人造好了。
💡 记忆口诀:Tomcat = Servlet 的房东。你只管"客人来了怎么招待",房租水电(端口、HTTP 解析、线程调度)房东全包。
⚠️ 常见错误
- 启动后访问 404:应用没放进
webapps目录,或访问路径写错。为什么?Tomcat 默认部署目录就是webapps,不在这个目录下的应用它根本不知道。怎么避免?把编译好的项目拷进webapps,再用"应用名 + 路径"访问。 - 端口被占用:报
Port 8080 was already in use,说明别的程序占着 8080。为什么?每个端口同时只能有一个程序监听,先启动的占着不走。怎么避免?改端口(conf/server.xml)或结束占用进程(Windows 用netstat -ano查 PID)。 - 分不清静态和动态:静态页面放
webapps/应用名/下直接可访问;动态页面必须靠 Servlet 程序生成。为什么容易错?因为二者访问时都走浏览器,看起来差不多。怎么区分?动态页面通常带参数(?xxx=yyy)或路径里有/servlet、.do之类后缀。 - 改完代码不重启 Tomcat:Java 改了类要重新编译、重启或热部署才生效,直接刷新浏览器看到的是旧页面。为什么?JVM 加载类一次后不会自动重新读取。怎么避免?开发期用 IDE 的热部署插件,或养成"改完就重启"的习惯。
📌 双语术语表(本讲)
| 中文 | English | 记忆点 |
|---|---|---|
| 万维网 | World Wide Web (Web) | 跑在互联网上的"网页服务" |
| 浏览器 | Browser | 最常用的客户端 |
| 客户端 | Client | 主动发请求的一方 |
| 服务器 | Server | 保存和处理资源的一方 |
| 请求 | Request | 顾客下的单 |
| 响应 | Response | 商家给的结果 |
| 统一资源定位符 | URL | 网页世界的快递单 |
| 协议 | Protocol | 双方对话的规则 |
| 主机名 | Host | 服务器的名字 |
| 端口 | Port | 服务器上的门牌号 |
| 查询参数 | Query String | 捎给服务器的附加信息 |
| 域名系统 | DNS | 查 IP 的电话簿 |
| 静态网页 | Static Page | 现成的海报 |
| 动态网页 | Dynamic Page | 现场做的海报 |
| Web 容器 | Web Container | Servlet 的房东 |
⭐ 本讲考点清单
- Web 的运作本质是"请求-响应"一问一答:浏览器是客户端,服务器负责保存和处理资源。
- 客户端-服务器架构:客户端主动请求、服务器被动响应,服务器常年在线、宕机业务即停。
- URL 六大组成:协议、主机名、端口、路径、查询参数、锚点;端口省略默认 80/443。
- 查询参数以
?开头、&连接多个键值对;#后的锚点不会发给服务器。 - HTTP 请求和响应都是纯文本报文,请求由"方法 + URL + 头部(+ 可选请求体)"构成。
- DNS 把域名解析成 IP 地址,相当于全球电话簿,且沿途多级缓存。
- 一次完整请求六步:输入网址 → DNS → TCP 连接 → 发请求 → 服务器处理 → 浏览器渲染。
- 静态网页内容写死、响应快;动态网页运行时生成、千人千面。
- Web 容器(Tomcat)负责监听端口、解析 HTTP、管理 Servlet 生命周期、处理并发。
- 请求-响应默认"无状态":一问一答、答完就散,想要记忆要靠 Cookie / Session。
- 常见排错链:DNS 挂了 → 无法解析;端口不通 → 连接失败;404 → 资源不存在。