diff --git a/blog/Web的历史1️⃣-HTTP.md b/blog/Web的历史1️⃣-HTTP.md index 0bbad91..731c61e 100644 --- a/blog/Web的历史1️⃣-HTTP.md +++ b/blog/Web的历史1️⃣-HTTP.md @@ -1,19 +1,26 @@ # Web的历史1️⃣-HTTP -## 起源 +*注:这些文章本来是打算作为开发组后端培训文本的开篇而写的,但是我发现文章的内容过于复杂且有点离题,所以稍微修改了一下单独作为3篇独立的文章发布。* + +*本文章的许多图片都直接来自 [MDN](https://developer.mozilla.org),在这里先感谢图片的创作者。* + +## 网络的起源 人们最初发明网络的目的很简单:在不同的电脑之间传输文件。那个时候没有U盘,也没有蓝牙,计算机领域的前辈们必须从头设计一个高效的传输文件的办法。 假如我们的电脑上有一个文件`example.docx`,放在我们电脑的文件夹`documents`里面,我们如何使用最原始的方法把它传递给另外一台电脑呢? -首先为这台电脑分配一个IP地址,IP地址是一台电脑在互联网上唯一标识,例如我们电脑的的IP地址是`123.45.67.89`;我们在这台电脑上启动一个“HTTP服务程序”;在程序的设置里指定"根目录"是我们存放文件的文件夹`documents`。 +早期的程序员编写了一类叫做"HTTP服务器"的程序,程序的功能是选择电脑上的一个文件夹,将这个文件夹暴露在互联网上共所有人操作。这个文件夹叫做HTTP服务的“根目录”。 -这个HTTP服务程序的作用是把你电脑上一个指定的文件夹(我们称为“根目录”)暴露在互联网上,所有人都可以下载这个文件夹下的文件。 +要使用这个程序,我们还要先给电脑分配一个IP地址,IP地址是一台电脑在互联网上的唯一标识,假如我们电脑的的IP地址是`123.45.67.89`。我们在这台电脑上启动一个HTTP服务程序。在程序的设置里指定根目录是我们存放文件的文件夹`documents`。 -这个时候,打开另一台电脑,在浏览器地址栏中输入`http://123.45.67.89/example.docx`,这时候就会发生神奇的事情:浏览器会提示你下载`example.docx`,这样,文件就从一台电脑传输到了另一台电脑。 +前面说过,这个HTTP服务程序的作用是把你电脑上一个指定的文件夹(我们称为“根目录”)暴露在互联网上,所有人都可以下载这个文件夹下的文件。于是这个时候,我们打开随便另一台电脑(前提是有网),在浏览器地址栏中输入`http://123.45.67.89/example.docx`,这时候就会发生神奇的事情:浏览器会提示你下载`example.docx`,这样,文件就从一台电脑传输到了另一台电脑。 假如`documents`文件夹下面还有另外一个文件`hi.txt`,那么当你在浏览器地址栏中输入`http://123.45.67.89/hi.txt`时,你就会发现浏览器显示了`hi.txt`这份文件的内容,因为浏览器可以直接显示`txt`文件,而不能直接显示`docx`文件。 + +*IIS是Windows官方的HTTP服务器,有着图形化的配置界面,其它大部分HTTP服务器都需要通过命令行和配置文件进行配置。* + ## HTTP协议 等等,刚才所讲的操作为什么能发生呢?当我在浏览器中输入网址并按下回车键的时候,这一切的背后到底发生了什么? @@ -22,11 +29,14 @@ HTTP协议,是`HyperText Transfer Protocol`的缩写,即"超文本传输协议"。是通过网络在电脑之间进行文件传输的默认协议。进行HTTP文件传输的双方,一个称之为”客户端“(Client),一个称之为"服务端"(Server)。 -我们刚才就是在我们的电脑上部署了HTTP服务端,而浏览器就是我们通信中的客户端.一次完整的HTTP协议由客户端请求(Request)和服务端响应(Response)组成;**在HTTP协议中,总是由客户端先发起一次HTTP请求,然后由服务端返回这次请求的响应,这样才是一次完整的HTTP通信。** +我们刚才就是在我们的电脑上部署了HTTP服务端,而浏览器就是我们通信中的客户端.一次完整的HTTP协议由客户端请求(Request)和服务端响应(Response)组成。**在HTTP协议中,总是由客户端先发起一次HTTP请求,然后由服务端返回这次请求的响应,这样才是一次完整的HTTP通信。** + + + HTTP协议不仅可以获取一个文件(就像我们所做的),也可以向服务端上传一个文件,或是修改服务端目录下某个文件的内容... -一次HTTP通信需要进行的操作(获取or上传等)由HTTP通信的“方法”指定,方法是请求头的一部分。 +一次HTTP通信要进行什么操作(获取or上传等),由HTTP通信的“方法”指定,方法是请求头的一部分。 下面我们介绍HTTP协议的具体内容: @@ -41,29 +51,35 @@ HTTP协议不仅可以获取一个文件(就像我们所做的),也可以向 - User-Agent:说明客户端是什么(是一个浏览器,还是命令行工具,还是爬虫?) - 自定义参数:除了上面的需要传输的标准内容,客户端还可以发送一些自定义的内容给服务端,这些内容总是以`Key=Value`的形式存在。 -比如`content-encoding=gzip`,就是要求服务端把数据用`gzip`压缩之后传输过来,方便节省带宽。参数是放在地址栏里传输的,在正常的URI之后以`?`开头,以`&`分割,例如,一次完整的HTTP请求是:`http://123.45.67.89/example.docx?content-encoding=gzip&greeting=hello` +举个例子,百度的搜索接口是`GET http://baidu.com/s`,要传递搜索内容到这个接口中,需要通过URL参数`wd`。如果你想用百度搜索东西,可以在地址栏里面输入`http://baidu.com/s?wd=你要搜的东西`,这就是URL参数的意义:向服务器传递一些自定义信息。 -参数的内容不是HTTP标准,也就是服务端如何理解参数完全靠程序员的设置,如果程序员设置了`gzip`有关代码,那我们的参数才有意义,否则这些参数完全不起作用。 +参数的内容不是HTTP标准,也就是服务端如何理解参数完全靠程序员写的代码。比如谷歌的用户搜索接口就是`GET http://google.com/search?q=你要搜的东西`。 #### HTTP方法 HTTP方法定义了这个请求具体要对指定的文件做什么,其中: -- `GET`:获取指定文件的内容; +- `GET`:获取指定文件的内容。 - `POST`:上传一个文件,内容放在请求体(下面会讲到) -- `PUT`:更新指定的文件,如果没有就创建一个 -- `PATCH`:修改指定的文件 -- `DELETE`:删除指指定的文件 -我们日常使用浏览器,比如在地址栏中输入`baidu.com`,其实就是在对这个地址做GET请求,浏览器会把你的输入内容自动补全成 `GET http://www.baidu.com/` ,我们一般使用浏览器,没法手动做出除了GET之外的请求,但是其他请求今天又被经常使用,这其实是前端脚本在工作,以后会解释. +其实这里还有一些方法的,我们以后讲。 + +我们日常使用浏览器,比如在地址栏中输入`baidu.com`,其实就是在对这个地址做GET请求,浏览器会把你的输入内容自动补全成 `GET http://www.baidu.com/` 这一HTTP请求 + +在浏览器地址栏里直接输入网址,默认就是发送GET请求。你可能会好奇,POST这些请求是怎么发出去的呢?这通常是由网页中的JavaScript代码在背后发送的。我们在之后的内容会讲到这一点。 + + + ##### 请求体 -对于某些方法,需要在请求时向服务器夹带一些东西(比如POST,PUT,PATCH需要你带上新文件的内容),请求体就是装载这些东西的. +对于某些方法,需要在请求时向服务器夹带一些东西(比如POST需要你带上新文件的内容),请求体就是装载这些东西的. 像GET请求就没有请求体,因为GET请求不需要夹带信息. -:::tip 提示 +:::tip[提示] -浏览器虽然正常情况下没法做出GET外的请求,但是浏览器在控制台里是可以自定义请求的,以`Firefox`为例,在F12的`Network`一栏中点`New Request`(有一个加号)就可以发送自定义请求;例如`curl`等HTTP命令行工具也可以发送请求,专业一点的例如`Postman`是一个专业的HTTP测试工具,可以满足很多复杂的要求 +浏览器虽然正常情况下没法做出GET外的请求,但是浏览器在控制台里是可以自定义请求的,以`Firefox`为例,在F12的`Network`一栏中点`New Request`(有一个加号)就可以发送自定义请求。`curl`等HTTP命令行工具也可以发送请求. + +实际上,HTTP协议中的“客户端”不仅仅是指浏览器,我们通常用的浏览器就是最常见的客户端,但其实像curl这样的命令行工具,或者手机APP,或者是浏览器里的JavaScript代码,当它们向服务器请求数据时,也扮演着客户端的角色。 ::: @@ -75,6 +91,8 @@ HTTP方法定义了这个请求具体要对指定的文件做什么,其中: 回应体就是包含了回应的主体内容了,如果是GET请求的话,那么就回应了所GET文件的内容,如果是其他请求的话,可能也会没有回应体,具体看使用的方法 + + #### 一个例子 `GET`方法从服务器获得一个资源,我们在浏览器的地址栏输入一个地址时,就是在对这个URI做`GET`请求,前面的例子也是通过`GET`方法来进行的。 @@ -82,31 +100,55 @@ HTTP方法定义了这个请求具体要对指定的文件做什么,其中: `POST`方法向服务器上传一个资源,例如使用某个客户端发送`POST http://example.org/sheet.xlsx`,在request body里面带上你的这个文件,那么`example.org`网站的根目录下就会多出一个叫做`sheet.xlsx`的文件 + 除了上面介绍的这些方法,还有`DELETE`,`PATCH`等方法,分别对应了删除,修改一个资源,你可以在你的电脑上通过`curl`等程序,或者通过浏览器控制台来进行常规的`GET`之外的方法请求 -:::tip 提示 +:::tip[提示] httpbin.org 这个网站可以让你试验HTTP协议的方法 ::: +:::info[HTTPS] + +HTTP在网络上是明文传输的,也就是说客户端和服务器之间的每个网络节点,每个人都可以看到。这显然不方便隐私,所以人们发明了HTTPS,也就是把HTTP的正文加密了,HTTPS可以说是当今互联网的基石,有了HTTPS,我们才能放心地在网上输入密码,用银行卡付款等。 + +::: + ### 网页与HTML -随着网络的发展,人们发现互联网的潜力远不止于传输文件。特别是浏览器的普及,人们希望能直接在网页上展示丰富的信息,而不只是把浏览器当作下载工具。前面我们说过了,浏览器可以直接展示`txt`文件,但是最大的问题是,`txt`文件是没有样式的。 +随着网络的发展,人们发现互联网的潜力远不止于传输文件。特别是浏览器的普及,人们希望能直接在网页上展示丰富的信息,而不只是把浏览器当作下载工具。前面我们说过了,浏览器可以直接展示txt文件,但是最大的问题是,txt文件是没有样式的。 比如:txt无法设置字体大小和颜色,无法加粗、倾斜文字,无法创建表格和列表,无法插入图片和链接。这些都是txt的局限。 -为了解决这个问题,人们发明了`HTML`(HyperText Markup Language),就是“超文本标记语言”,HTML的核心思想是:在普通文本中加入特殊的标记,告诉浏览器如何显示内容。 +为了解决这个问题,人们发明了HTML(HyperText Markup Language),就是“超文本标记语言”,HTML的核心思想是:在普通文本中加入特殊的标记,告诉浏览器如何显示内容。 -比如`你好~`就是指示浏览器显示`你好~`这段文字,并且以斜体的方式。你可以像打开`txt`文件一样打开`html`文件,只不过浏览器默认是加载渲染之后的界面而不是raw HTML +比如`你好~`就是指示浏览器以斜体的方式显示`你好~`这段文字。你可以用系统自带的笔记本像打开txt文件一样打开HTML文件,只不过浏览器默认是加载渲染之后的界面而不是原始的HTML。 除HTML之外,人们还发明了CSS与HTML搭配使用,CSS可以对样式做更复杂高级精细的控制,这里就不细说了 回到我们的主题,不管使用的是什么方法,操作的是什么文件,HTTP协议传输的对象都是一些固定静态的文件,其内容在服务器上是固定不变的(除非手动修改),这样的网页称为静态网页。 -静态网页中,所有用户看到的内容都相同,内容不会根据用户行为动态变化 -,服务器只负责传输文件,不进行复杂计算。 +静态网页中,所有用户看到的内容都相同,内容不会根据用户行为动态变化,服务器只负责传输文件,不进行复杂计算。 -我们的wiki就是静态网页,在服务端上都对应着html页面,只不过加了非常多的样式显得很高级。 +我们的wiki就是静态网页,在服务端上都对应着HTML页面,只不过加了非常多的样式显得很高级。 很多常见的网站(如企业官网、技术文档、个人博客等)都是静态网页,虽然看起来很精美,但本质上就是经过精心设计的HTML和CSS文件。 + + + +:::info + +这是三篇系列文章中的第**1**篇 + +点击以跳转: + +**HTTP**(你在看的文章) + +[动态网页](/blog/Web的历史2️⃣-动态网页) + +[Web应用](/blog/Web的历史3️⃣-Web应用) + +::: + + diff --git a/blog/Web的历史2️⃣-动态网页.md b/blog/Web的历史2️⃣-动态网页.md index cc58d60..5faede5 100644 --- a/blog/Web的历史2️⃣-动态网页.md +++ b/blog/Web的历史2️⃣-动态网页.md @@ -1,2 +1,286 @@ # Web的历史2️⃣-动态网页 + +上篇文章我们已经了解了静态网页是如何工作的,但是这样的网页是不能满足大家对互联网的需求的。举例子来说:你访问b站首页`bilibili.com`,每次刷新,首页上显示给你的视频都不一样,不同的人访问这个首页,显示的也不一样,按理说大家都是访问一个网址,背后应该都是同一个文件,为什么每个人都不一样呢?这种功能是如何实现的? + +淘宝上有数不清的商品在售卖,如果淘宝为每一个商品都在服务器目录下面创建一个html文件,好让大家通过访问`http://taobao.com/someproduct.html`来查看商品信息,那这个工作量就非常大了。而且,这样的网页,基本上没有交互的功能:我们希望用户可以点击按钮就能购买商品,商家在网页后台上操作就能上传商品。这种功能应该如何实现呢? + +暂时先不考虑这些高级的问题,让我们先从最基础的讲起: + +## 服务器端内嵌(SSI) + +如果你想向网站中插入动态内容,SSI是最简单,最直接的办法,比如我们的wiki有许多页面,但是每个页面都有一些共同的元素:页面头部的导航栏,左侧的列表,页脚等。如果为每个页面都复制一份相同的HTML的话,那就太麻烦了,有没有什么办法,可以使HTML一次编写,到处渲染呢? + +SSI(Server Side Includes)就是满足这种需求的一个HTML宏语言。它有点类似于C语言的`# include`宏: + +假设这是我们首页的HTML: + +```html +
当前时间:'$(date)'
' +echo '内存使用情况:
' +echo '' +free -h +echo '' +echo '' +echo '' + +``` + +每次用户访问这个页面,都会看到实时的系统信息,真正实现了动态内容。 + +虽然CGI现在很少见了,但它建立了一个重要概念:将URL请求映射到程序函数,而不是静态文件。这个思想成为了现代Web开发的基础。 + +## 嵌入式脚本 +随着动态网页需求的增长,纯CGI编程变得复杂。程序员们希望能够在HTML中直接编程动态代码,这样既保持了HTML的可读性,又能实现动态功能。 + + +这个就是嵌入式脚本,顾名思义就是把脚本和HTML混在一起,在HTML中嵌入脚本; + +但是这种脚本和今天的前端JavaScript不同,它是由后端解释执行的,在返回HTML响应之前,HTTP服务程序会检查这个HTML里面有没有可以执行的脚本内容,有的话就执行这些脚本,并且把脚本的输出嵌入到HTML里面。任何有效的HTML也是有效的这类脚本语言。 + +从CGI到嵌入式脚本的另外一个关键驱动力是性能。CGI每来一个请求,服务器就得创建一个新进程去运行CGI程序,完成后再销毁,开销很大。而嵌入式脚本通常则是直接作为服务器的一部分运行,效率远高于CGI。 + +### JSP + +举个例子吧,你可以轻松使用Java来创建动态网页,只需要把Java代码嵌入到HTML里面,使用`<% %>`包裹住代码: + +```java + + + +
当前时间:<%= new java.util.Date() %>
+ + + + +``` + +复杂一点的例子: + +```java + + + +当前服务器时间:<%= new java.util.Date() %>
+您是第 <%= session.getAttribute("visitCount") %> 位访客
+ + <%-- 这是JSP注释,不会出现在最终HTML中 --%> + <% + // 这里可以写复杂的Java逻辑 + String userName = request.getParameter("user"); + if (userName != null) { + out.println("欢迎您," + userName + "!
"); + } + %> + + + +``` + +:::info[session和cookie] + +在这段JSP代码中有一个对象叫做`session`,这是什么呢?实际上,因为HTTP是无状态的协议,意味着两次请求之间是完全独立的,一次请求不应该依赖另一次请求。这显得有点不灵活,于是人们会在HTTP的请求体上夹带一些额外的参数,用于表明用户的身份信息,比如在用户登录网站之后,服务器会给客户端一个密钥,下一次客户端请求页面是带上这个密钥,服务器就知道这是某个用户的请求。在这种模式下,服务器需要为每个用户维护信息,比如最简单地需要维护密钥是对应哪个用户的,这些信息就叫做session。 + +::: + +类似于这样的脚本叫做JSP(JavaServer Pages),它在后端返回时被转换成Java Servlet代码来执行,本质上,JSP是Java Servlet的一种语法糖。至于JSP和Java Servlet都是什么,自行了解吧。 + +### PHP +比JSP更灵活的就是PHP,PHP就是一门纯正的脚本语言了,它的用法与JSP类似,使用`包裹代码`: + +```php + + + +当前时间:$time
"; +echo "