## 2. web页面开发基础 ### 2.1 HTTP协议(重点掌握) 推荐阅读 [《图解http》读书笔记](https://juejin.cn/post/6903526294806331400) [pdf下载](./resources/《图解http》读书笔记%20-%20掘金.pdf) [PPT](./resources/HTTP协议-黑马.pptx) [TCP/IP网络模型](https://www.cnblogs.com/phpstudy2015-6/p/6804202.html) #### 2.1.1 URI、URL、URN - URI = Uniform Resource Identifier 统一资源标志符 > URI是抽象的定义,不管用什么方法表示,只要能标识一个资源,就叫URI. URI包括URL和URN.后来urn没流行起来,导致几乎目前所有的uri都是url。 - URL = Uniform Resource Locator 统一资源定位符 > 是URI的子集,又称统一资源定位器、定位地址、URL地址,俗称网址,是因特网上标准的资源的地址,作用是为了告诉使用者某个资源在 Web 上的地址。URL包含访问资源所需的协议类型(如HTTP、HTTPS、FTP)和资源的网络位置(如域名和文件路径) - URN = Uniform Resource Name 统一资源名称 > 指的是资源而不指定其位置或是否存在. URN 的一个最好的例子是 ISBN 号,它被用来唯一地识别一本书。URN 与 URL 完全不同,因为它不包含任何协议。 三者的关系图示: ![](./resources/uri-url-urn.png) --- URL结构定义: ![](./resources/url.png) ```text 模式( schema ),相当于 URL 的类型,通常用来表示访问协议,比如 HTTP ; 用户信息( userinfo ),用于访问资源的用户信息,可选; 主机( host ),资源所在主机,可选; 端口( port ),资源所在主机端口,可选,不填则使用协议的默认端口; 路径( path ),资源所在路径; 查询( query ),用于访问资源的参数,比如网页传参,可选; 片段( fragment ),指定资源中的某个片段,比如网页中的锚,可选; ``` URL示例分析: ![](./resources/url-example.png) 其他类型URL示例: ```text ftp://ftp.is.co.za/rfc/rfc1808.txt https://www.ietf.org/rfc/rfc2396.txt ldap://[2001:db8::7]/c=GB?objectClass?one mailto:John.Doe@example.com news:comp.infosystems.www.servers.unix telnet://192.0.2.16:80/ file:///c:/ ``` #### 2.1.2 浏览器与web服务器的交互过程 基本过程: ![](./resources/web-flow-with-dns.png) 动态页面交互过程: ![](./resources/web_application_with_html_and_steps.png) #### 2.1.3 HTTP请求包结构 [HTTP 消息结构](https://www.runoob.com/http/http-messages.html) ![](./resources/imgs/http-request-struct.png) #### 2.1.4 HTTP请求方法 [HTTP 请求方法](https://www.runoob.com/http/http-methods.html) #### 2.1.5 HTTP请求头 [HTTP Request Header 请求头](https://stackoverflow.org.cn/httpheader/) #### 2.1.6 HTTP响应包结构 ![](./resources/imgs/http-response-struct.png) #### 2.1.7 HTTP状态码 - **2xx 成功:** 请求已成功被服务器接收、理解,并接受。 - **200 OK:** 请求已成功,请求所希望的响应头或数据体将随此响应返回。 - **3xx 重定向:** 需要客户端采取进一步的操作才能完成请求。 - **301 Moved Permanently:** 请求的资源已被永久移动到新位置。 - **302 Found:** 服务器目前从不同位置的资源响应请求,但请求者应继续使用原有位置来进行以后的请求。 - **4xx 客户端错误:** 请求包含语法错误或无法完成请求。 - **400 Bad Request:** 服务器不理解请求的语法。 - **401 Unauthorized:** 请求要求用户的身份认证。 - **403 Forbidden:** 服务器理解请求客户端的请求,但是拒绝执行此请求。 - **404 Not Found:** 请求失败,请求所希望得到的资源未被在服务器上发现。 - **5xx 服务器错误:** 服务器在处理请求的过程中发生了错误。 - **500 Internal Server Error:** 服务器遇到某种不可预知的情况。 - **503 Service Unavailable:** 由于临时的服务器维护或者过载,服务器当前无法处理请求。 #### 2.1.8 HTTP响应头 [HTTP Response Header 响应头](https://stackoverflow.org.cn/httpheader/) #### 2.1.9 Cookie 参考阅读: [HTTP Cookie](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies) HTTP 是无状态协议,说明它不能以状态来区分和管理请求和响应。也就是说,无法根据之前的状态进行本次的请求处理。 而在实际应用中我们又希望能够保持用户的状态,为解决这个问题,Cookie诞生了,在保留无状态协议这个特征的同时又要解决类似记录状态的矛盾问题。 HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器——如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。 Cookie 主要用于以下三个方面: - 会话状态管理 > 如用户登录状态、购物车、游戏分数或其他需要记录的信息 - 个性化设置 > 如用户自定义设置、主题和其他设置 - 浏览器行为跟踪 > 如跟踪分析用户行为等 **创建 Cookie** 服务器收到 HTTP 请求后,服务器可以在响应标头里面添加一个或多个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,并将其放在 HTTP Cookie 标头内,向同一服务器发出请求时一起发送。你可以指定一个过期日期或者时间段之后,不能发送 cookie。你也可以对指定的域和路径设置额外的限制,以限制 cookie 发送的位置。关于下面提到的头部属性的详细信息,请参考 Set-Cookie 文章。 服务器使用 Set-Cookie 响应头部向用户代理(一般是浏览器)发送 Cookie 信息。这指示服务器发送标头告知客户端存储一对 cookie: ```http HTTP/1.0 200 OK Content-type: text/html Set-Cookie: yummy_cookie=choco Set-Cookie: tasty_cookie=strawberry ``` 现在,对该服务器发起的每一次新请求,浏览器都会将之前保存的 Cookie 信息通过 Cookie 请求头部再发送给服务器。 ```http GET /sample_page.html HTTP/1.1 Host: www.example.org Cookie: yummy_cookie=choco; tasty_cookie=strawberry ``` #### 2.1.10 Session Session表示会话,服务器端用来跟踪用户状态的一种机制。在java web中session是一个存储在WEB服务器端的java对象,该对象代表用户和WEB服务器的一次会话。 > 那什么才叫一次会话呢? >> 一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束。 >> >> 本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义的一次完整会话。 **Session的工作原理与限制** - 服务器端用来跟踪用户状态的一种机制。 - Session 通常使用Cookie来传递Session ID。 - 服务器通过Session ID来查找与特定用户相关的数据。 - session的使用要求用户浏览器必须支持cookie,如果浏览器不支持使用cookie,或者设置为禁用cookie,那么将不能使用session。 ### 2.2 HTML/CSS/JavaScript基础 [PPT](./resources/网页开发基础-黑马.pptx) #### 2.2.1 HTML5基础知识 (掌握) [HTML常用知识点总结笔记](https://blog.csdn.net/qq_42002794/article/details/118356086) [使用 HTML 构建 Web](https://developer.mozilla.org/zh-CN/docs/Learn/HTML) HTML(HyperText Markup Language,超文本标记语言)是一种用来告知浏览器如何组织页面的标记语言。 HTML 由一系列的元素组成,这些元素可以用来包围或标记不同部分的内容,使其以某种方式呈现或者工作 HTML 元素(标签)的主要部分: ![](./resources/imgs/grumpy-cat-small.png) ``` 开始标签(Opening tag):包含元素的名称(本例为 p),被左、右角括号所包围。开头标签标志着元素开始或开始生效的地方。在这个示例中,它在段落文本的开始之前。 内容(Content):元素的内容,本例中就是段落的文本。 结束标签(Closing tag):与开始标签相似,只是其在元素名之前包含了一个斜杠。这标志着该元素的结束。没有包含关闭标签是一个常见的初学者错误,它可能会产生奇特的结果。 ``` 元素也可以拥有属性,属性看起来像这样: ![](./resources/imgs/grumpy-cat-attribute-small.png) 属性包含元素的额外信息,这些信息不会出现在实际的内容中。在上述例子中,这个 class 属性是一个识别名称,以后为元素设置样式信息时更加方便。 属性必须包含: ``` 一个空格,它在属性和元素名称之间。如果一个元素具有多个属性,则每个属性之间必须由空格分隔。 属性名称,后面跟着一个等于号。 一个属性值,由一对引号("")引起来。 ``` #### 2.2.2 CSS (了解) [B站视频-为初学者准备的:CSS 速成](https://www.bilibili.com/video/BV1bW411R7hg/?spm_id_from=333.337.search-card.all.click&vd_source=fb252f6c305362a2870fb7388465df99) [学习使用 CSS 为 HTML 添加样式](https://developer.mozilla.org/zh-CN/docs/Learn/CSS) ![](./resources/imgs/html-rendering.svg) **CSS 语法:** ``` 选择器 { 属性名: 属性值; 属性名: 属性值; ... } ``` > 示例: ```css body { background-color: #f0f0f0; } ``` ##### 2.2.2.1 CSS选择器 CSS选择器用以筛选出要添加样式的元素。 | 选择器类型 | 解释 | 示例 | | ------------ |-----------------------------------| -------------------------------- | | **元素选择器** | 也叫标签选择器,通过标签名选取元素 | `p { color: red; }` 选取所有 `
` 元素,将文本颜色设置为红色。 | | **类选择器** | 通过类名选取元素 | `.my-class { font-weight: bold; }` 选取具有类名为 `my-class` 的元素,使其字体加粗。 | | **ID选择器** | 通过ID名称选取唯一元素 | `#unique-id { background-color: yellow; }` 选取ID为 `unique-id` 的元素,背景色设为黄色。 | | **通配符选择器** | 匹配所有元素 | `* { margin: 0; padding: 0; }` 选取所有元素,清除默认的外边距和内边距。 | | **属性选择器** | 根据属性及值选取元素 | `[target="_blank"] { color: blue; }` 选取带有属性 `target` 且值为 `_blank` 的元素,如外部链接,文本颜色设为蓝色。 | | **伪类选择器** | 选取基于状态的元素,如 `:hover`, `:active` 等 | `a:hover { text-decoration: underline; }` 鼠标悬停在链接上时,显示下划线。 | | **伪元素选择器** | 选取元素的特定部分,如 `::before`, `::after` | `p::first-letter { font-size: 2em; }` 选取段落的第一个字母,字体大小设为2倍。 | | **相邻兄弟选择器** | 选取紧接在另一元素后的同级元素 | `h1 + p { text-indent: 2em; }` 使紧跟在 `
` 首行缩进2个字符。 | | **一般兄弟选择器** | 选取拥有相同父元素的元素,不论位置 | `div ~ p { color: green; }` 选取所有 `
` 元素,文本颜色设为绿色。 | | **子元素选择器** | 选取直接子元素 | `ul > li { list-style-type: square; }` 将 `
` 元素,行高设为1.5。 | ##### 2.2.2.2 盒模型 盒子模型是CSS布局中的一个重要概念,它将HTML文档中的每个元素都视为一个矩形的盒子。这个盒子由四个主要部分组成:内容(Content)、内边距(Padding)、边框(Border)和外边距(Margin)。这四个部分共同决定了元素在页面上的实际尺寸和位置。 ![](./resources/imgs/css-box-1.png) ![](./resources/imgs/css-box.png) 在HTML中所有标签分为两类,分别是容器级和文本级标签。 在CSS中也将所有标签分为两类,分别是块级元素和行内元素。 - HTML中容器级与文本级 ``` 容器级标签:可以嵌套其他的所有标签 div、h、ul>li、ol>li、dl>dt+dd 文本级标签:只能嵌套文字、图片、超链接 span、p、buis、strong、em、ins、del ``` - CSS中块级元素与行内元素 ``` 块级:块级元素会独占一行,所有的容器类标签都是块级,文本标签中的p标签也是块级 div、h、ul、ol、dl、li、dt、dd、p 行内:行内元素不会独占一行,所有除了p标签以外的文本标签都是行内 span、buis、strong、em、ins、del ``` - 块级元素与行内元素的区别 ``` 1、块级元素block 独占一行 可以设置宽高 若没有设置宽度,那么默认和父元素一样宽(比如下例中的div的父元素是body,默认div的宽就是body的宽) 若没有设置宽高,那么就按照设置的来显示 2、行内元素inline 不会独占一行 不可以设置宽高 盒子宽高默认和内容一样 3、行内块级元素inline-block 不会独占一行 可以设置宽高 ``` 对于块级元素而言,如果书写模式是水平方向horizontal-tb,那么块是从上往下流;而书写模式是垂直方向horizontal-lr时,那么块是从左向右流。如下图所示: ![](./resources/imgs/block-boxes.png) 对于行内元素而言,它会按照当前上下文、书写模式和方向进行布局。它们的宽度取决于它们的内容,并且在任何有空间的地方相邻放置。如下图所示: ![](./resources/imgs/inline-boxes.png) #### 2.2.3 JavaScript基本语法和DOM操作(掌握) [现代 JavaScript 教程](https://zh.javascript.info/) [Github: 30-Days-Of-JavaScript](https://github.com/Asabeneh/30-Days-Of-JavaScript) ##### 2.2.3.1 基础语法 - **变量声明**:理解`let`, `const`, `var`的区别与使用场景。 - **数据类型**:掌握字符串、数字、布尔值、数组、对象等基本数据类型。 - **运算符**:算术、比较、逻辑运算符以及三元表达式等。 - **条件语句**:if...else, switch...case等。 - **循环结构**:for, while, do...while循环的应用。 - **函数定义与调用**:了解如何定义及调用函数,参数传递方式。 - **数组操作**:数组的创建、遍历方法(如map(), filter(), reduce())。 - **对象操作**:创建对象字面量、属性访问、构造函数。 - **错误处理**:try...catch...finally语句。 ```javascript try { // 可能引发异常的代码 console.log('try块中的代码'); } catch (error) { // 异常处理代码 console.log('发生了一个错误:', error.message); } finally { // 无论是否发生异常,这里的代码都会被执行 console.log('finally子句中的代码'); } ``` ##### 2.2.3.2 面向对象编程 - **类与对象**:理解类的声明、实例化和继承。 - **继承机制**:理解原型继承和类继承的区别。 ##### 2.2.3.3 DOM操作 - **文档对象模型**:DOM树结构介绍。 - **选择元素**:getElementById(), getElementsByClassName(), querySelector()等方法。 - **修改内容**:innerHTML, textContent属性。 - **事件绑定**:addEventListener(), removeEventListener()。 - **样式操作**:className, style属性。 - **创建/删除节点**:createElement(), appendChild(), removeChild()。 #### 2.2.3.4 ES6+特性 - **箭头函数**:简化函数定义。 > ES6允许使用 “箭头”( => )定义函数。 ```javascript let v = v => v; // 等同于 let f = function(f){ return f; }; ``` > 如果箭头函数 不需要参数 或 需要多个参数 ,就在剪头前使用()括起来参数部分。 ```javascript let f = () => 5; // 等同于 let f = function() { return 5 }; let sum = (num1, num2) => num1 + num2; // 等同于 let sum = function(num1, num2){ return num1 + num2; }; ``` > 箭头函数的一个用处是简化回调函数。 ```javascript // 普通函数写法 let values = [2,5,8,6] let result = values.sort(function (a, b){ return a - b }) console.log(result) // 2,5,6,8 // 箭头函数写法 let values = [2,5,8,6] let result = values.sort((a, b) => a - b) console.log(result) // 2,5,6,8 ``` **使用注意点** > 箭头函数没有自己的 this 对象。 > > 不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。 > 对于普通函数来说,内部的 this 指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的。 ```javascript function Timer(){ this.s1 = 0 this.s2 = 0 // 箭头函数 setInterval(() => { this.s1++; console.log("****", this); }, 1000) // 普通函数 setInterval(function (){ this.s2++ console.log("####", this) }, 1000) } var timer = new Timer() setTimeout(() => console.log('s1: ', timer.s1),3200) //s1: 3 setTimeout(() => console.log('s2: ', timer.s2),3200) //s2: 0 ``` - **模板字符串**:使用反引号(``)创建字符串。 > JavaScript 模板字符串(template string)是一种字符串字面量,使用反引号(`)来标识。它可以包含普通字符以及特殊的占位符。 > 模板字符串中可以包含变量,其写法是在变量名前面加上${,后面跟上}。当模板字符串被执行时,这些变量会被相应的值替换。 ```javascript const name = 'Alice'; const age = 25; const greeting = `Hello, my name is ${name} and I am ${age} years old.`; console.log(greeting); // 输出: Hello, my name is Alice and I am 25 years old. ``` > 模板字符串还可以内嵌表达式,例如: ```javascript const x = 10; const y = 20; const sum = `${x} + ${y} = ${x + y}`; console.log(sum); // 输出: 10 + 20 = 30 ``` > 模板字符串也可以用于多行字符串,不需要使用字符串连接,例如: ```javascript const multiLine = `This is a multi-line string.`; console.log(multiLine); ``` #### 2.2.4 字符集和字符编码(了解) [字符编码和字符集PPT](./resources/javaweb-week-02-chartset.pptx) [字符集和字符编码(Charset & Encoding)](https://www.runoob.com/w3cnote/charset-encoding.htm) 计算机中储存的信息都是用二进制数表示的;而我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果。通俗的说,按照何种规则将字符存储在计算机中,如'a'用什么表示,称为"编码";反之,将存储在计算机中的二进制数解析显示出来,称为"解码". 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。 字符编码(Character Encoding):是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,它是信息处理的一项基本技术。 常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。 - **ASCII字符集&编码** ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。 ASCII编码:将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使用7位(bits)表示一个字符,共128字符;但是7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。 - **GBXXXX字符集&编码** 中文字符集和编码: GB2312、GBK、GB18030 - **Unicode字符集&UTF编码:** 一种国际字符编码标准,支持世界上几乎所有的字符。 - - **UTF-8:** 基于Unicode的编码,兼容ASCII,广泛用于Web页面。 - - **UTF-16:** Unicode的另一种编码形式,JavaScript内部使用UTF-16。 ![](./resources/imgs/charset.png) #### 2.2.5 认识TypeScript(简单了解) [面向初学者的 TypeScript 完全指南](https://www.freecodecamp.org/chinese/news/learn-typescript-beginners-guide) TypeScript是一种由微软开发的开源编程语言。TypeScript是JavaScript的超集,意味着它能做JavaScript所做的一切,但有一些附加功能。 使用TypeScript的主要原因是为JavaScript添加静态类型。静态类型意味着变量的类型在程序中的任何时候都不能被改变。 TypeScript不能被浏览器理解,所以它必须由TypeScript编译器(TSC)编译成JavaScript。