客户端和服务器
网络就是用来通信的,我们来想想什么是通信,相信读者一定用过微信,我们是如何用微信进行通信的,无非就是我给你发一个消息,你再回复一个消息,这就完成了一次通信,在网络中也是这样,在网络中,两个应用程序之间要进行通信,无非就是一方发送一条消息,另一方回复一个消息,这就是通信,这里就涉及到一些专有名词。
首先,一次通信中,发送消息的那一方称为客户端,回复消息的那一方称为服务器。发出消息的过程叫做请求,回复消息的过程叫做响应,基于此,网络中的一次通信我们也称为一次请求响应。当客户端发出一个请求,服务器回复一个响应,这样就完成了一次通信。
以上说法并不适用于所有情况,只是我们现在不涉及
举个例子,当我们浏览器访问 www.baidu.com 的时候,实际上就是在和百度服务器进行一次通信,我们的浏览器作为客户端,会先告诉百度服务器,我需要访问百度首页,然后百度服务器就会收到这个请求,进行一些处理之后将百度首页的 HTML 代码响应给我们的浏览器,这样我们就可以成功访问百度首页了,这实际上就是一个请求响应的过程。
这里需要注意,不管是客户端和服务器,指的都不是一台计算机,而是一个应用程序,这就意味着,一台电脑可以同时是服务器和客户端,比如我们常用的 VSCODE 中的 live server 实际上就是在本地开了一个服务器,然后我们再通过浏览器去访问本地的服务器,此时我自己的电脑即是客户端也是服务器。
基于客户端和服务器这样的交互模式我们称为 CS 架构,而如果客户端为浏览器,那么我们就称为 BS 架构。
URL
所谓的 URL 的地址,说白了就是一个网址,例如 https://www.baidu.com 这个就是一个网址,也就是一个 URL 地址。
当我们访问 https://www.baidu.com 的时候,他会把百度的 HTML 文件返回给我们,此时我们就可以访问百度首页,这里读者可以注意到吧,访问 https://www.baidu.com 本质上是拿到了一个 HTML 文件,实际上,URL 地址是可以拿到各式各样的文件的,读者肯定见过那种下载链接,这些网址其实就是一个 URL 地址,比如一张图片的链接地址,一个压缩包的链接地址,这些其实都是 URL,所以 URL 本质上就是一个资源的链接地址。
一个完整的 URL 地址由以下部分组成:协议+主机+端口+路径+参数+哈希
这里我们举个例子介绍上面的组成:https://www.baidu.com:8080/test/2024?param1=3¶m2=4#main
在这个例子中,https 就是协议名,www.baidu.com 这个就是主机名,8080 就是端口名,/test/2024 就是路径,param1=3¶m2=4 就是参数,main 就是哈希。这就是一个完整的 URL 地址。
协议名和主机名使用
://进行分割,主机名和端口使用:进行分割,路径名和参数名使用?进行分割,参数和哈希使用#进行分割
由于端口必须是数字,而路径必须以/开头,所以端口和路径是不需要进行分割的
这里我们一个一个介绍他们都是干嘛的
- 协议:这里我们使用 http 或者 https 协议,协议这个概念比较抽象,读者如果有兴趣,可以参考计算机网络的知识,至于 http 和 https 这两个协议,我们会在后面详细展开。
- 主机:主机就是服务器的地址,服务器的地址就是 IP 地址,IP 地址由四个
0-255的数字组成,例如127.0.0.1就是一个 IP 地址,这个地址指向了我本地的服务器,但是 IP 地址是由 4 个数字组成,这往往非常难以记忆,为了方便我们记忆,就引入了域名,例如baidu.com就是一个域名,一个域名绑定了一个 IP 地址,我们通过访问域名就会自动跳转到 IP 地址,从而完成对服务器的访问,例如baidu.com这个域名绑定了百度服务器的 IP 地址,当我们访问这个域名的时候,会被自动转换为百度服务器的 IP 地址,这个转换过程是由 DNS 服务器完成的,这里不再展开,转换为服务器的 IP 地址后,就可以找到百度的服务器,从而和百度进行通信。对于我们本地的服务器,IP 地址就是127.0.0.1,也有一个特殊的域名,即localhost,这个域名指向的就是127.0.0.1这个地址。值得注意的是,如果我们使用的是 https 协议,我们是无法在域名使用 IP 地址来访问的,我们必须写域名。只有在 http 协议下我们才可以使用 IP 地址直接访问到服务器。当然,一些网站可能屏蔽了使用 IP 地址直接访问,此时我们就不能通过 IP 地址直接访问。 - 端口名:实际上,我们通过主机地址,也就是 IP 地址,是可以拿到一个服务器的地址的,但正如我们前面说的一样,服务器本身并不是一台电脑,而是一个应用程序,服务器也就是一个应用程序,我们要找到服务器,就要在这个电脑上找到服务器的应用程序,怎么找呢?就通过端口来找,一个应用程序,只要是联网的,就得至少占用一个端口,这其实很好理解,例如我这个电脑上有很多应用程序都要进行通信,此时我收到了一个消息,我如何判断这个消息是哪个应用程序的呢?就需要通过端口来判断。端口号是可选的,如果不写端口号,就会使用默认端口号,如果是基于 http 协议的服务器,端口号默认就是 80,如果是基于 https 协议的服务器,端口号默认就是 443。
- 路径:此时我们已经可以找到服务器了,但是服务器肯定不止存储一个资源对吧,一台服务器可能会存储很多资源,比如图片资源,比如网页资源,比如音频资源,我们的服务器必须合理管理这些资源以供我们能通过 URL 获取到,这些资源就被放在了一个目录里,也就是服务器的根目录,以一个目录的解构进行管理,说得通俗一点就是文件夹的形式进行管理,其中
/表示的就是根目录,/imgs/img.jpg表示的就是根目录下img文件夹下的img.jpg这个文件。当然,如果我们省略这个参数,指的就是访问根目录。 - 参数:实际上,服务器不仅可以给我们提供文件资源,还可以给我们提供一些数据服务,例如我希望客户端请求
https://myhost.com/news的时候访问到新闻列表的 JSON 数据,此时我完全可以没有这个news文件夹,我完全可以在服务器拦截这个请求,我发现访问的是/news文件夹,我服务器就知道他是想访问新闻列表,从而以一个 JSON 格式的形式将新闻列表丢给服务器。这里有一个问题,如果我的新闻列表很长很长,是不是就要进行分页,我要指定获取第几页的数据,就可以使用/news?page=n来表示拿到第 n 页的数据,当然,对于这样的简单筛选场景,更加推荐使用动态路由的方式,这里并不展开。起码读者到这里应该知道,参数实际上就是写给服务器的,例如读者可以观察一下,我使用访问搜索一个内容的时候,实际上拿到的都是同一个网址,只不过是参数发生了变化,而百度的服务器就是根据这个参数给我返回的搜索结果。当然,不管是路径还是参数,都是后端服务器去实习的,我们只需要看懂文档知道是什么意思即可。 - 哈希:在网络通信中,哈希没有什么作用,哈希在其他地方会有应用,例如锚链接,例如实现单页应用程序,由于他真的没有什么用处,所以这里不介绍。
读者会发现,我们平时访问网站时用到的网址好像不用写协议名,比如我直接写 www.baidu.com 就可以访问到百度。根本就没有协议名,实际上,对于以上的 URL 地址,其中除了协议和主机,其他都是可以省略的,当然,这里好像也没有协议是吧,实际上当我们不写协议的话,浏览器会给我们自动补全协议,注意,这个是浏览器自动补全的。
在 URL 地址中,是不允许出现非 ASCII 字符的,如果我们使用了其他字符,会自动经过 URL 编码算法进行转化