【Go入门】Web工作方式

【Go入门】 Web工作方式

我们平时浏览网页的时候,会打开浏览器,输入网址后按下回车键,然后就会显示出你想要浏览的内容。在这个看似简单的用户行为背后,到底隐藏了些什么呢?

对于普通的上网过程,系统其实是这样做的:浏览器本身是一个客户端,当你输入URL的时候,首先浏览器会去请求DNS服务器,通过DNS获取相应的域名对应的IP,然后通过IP地址找到IP对应的服务器后,要求建立TCP连接,等浏览器发送完HTTP Request(请求)包后,服务器接收到请求包之后才开始处理请求包,服务器调用自身服务,返回HTTP Response(响应)包;客户端收到来自服务器的响应后开始渲染这个Response包里的主体(body),等收到全部的内容随后断开与该服务器之间的TCP连接。

在这里插入图片描述

图3.1 用户访问一个Web站点的过程

一个Web服务器也被称为HTTP服务器,它通过HTTP协议与客户端通信。这个客户端通常指的是Web浏览器(其实手机端客户端内部也是浏览器实现的)。

Web服务器的工作原理可以简单地归纳为:

  • 客户机通过TCP/IP协议建立到服务器的TCP连接
  • 客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档
  • 服务器向客户机发送HTTP协议应答包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理得到的数据返回给客户端
  • 客户机与服务器断开。由客户端解释HTML文档,在客户端屏幕上渲染图形结果

一个简单的HTTP事务就是这样实现的,看起来很复杂,原理其实是挺简单的。需要注意的是客户机与服务器之间的通信是非持久连接的,也就是当服务器发送了应答后就与客户机断开连接,等待下一次请求。

URL和DNS解析

我们浏览网页都是通过URL访问的,那么URL到底是怎么样的呢?

URL(Uniform Resource Locator)是“统一资源定位符”的英文缩写,用于描述一个网络上的资源, 基本格式如下

scheme://host[:port#]/path/.../[?query-string][#anchor]
scheme         指定底层使用的协议(例如:http, https, ftp)
host           HTTP服务器的IP地址或者域名
port#          HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如 http://www.cnblogs.com:8080/
path           访问资源的路径
query-string   发送给http服务器的数据
anchor         锚

DNS(Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它从事将主机名或域名转换为实际IP地址的工作。DNS就是这样的一位“翻译官”,它的基本工作原理可用下图来表示。

在这里插入图片描述

图3.2 DNS工作原理

更详细的DNS解析的过程如下,这个过程有助于我们理解DNS的工作模式

  1. 在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。

  2. 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。

  3. 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。

  4. 如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。

  5. 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至 “根DNS服务器”,“根DNS服务器”收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。

  6. 如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管本地DNS服务器用的是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

在这里插入图片描述

图3.3 DNS解析的整个流程

所谓 递归查询过程 就是 “查询的递交者” 更替, 而 迭代查询过程 则是 “查询的递交者”不变。

举个例子来说,你想知道某个一起上法律课的女孩的电话,并且你偷偷拍了她的照片,回到寝室告诉一个很仗义的哥们儿,这个哥们儿二话没说,拍着胸脯告诉你,甭急,我替你查(此处完成了一次递归查询,即,问询者的角色更替)。然后他拿着照片问了学院大四学长,学长告诉他,这姑娘是xx系的;然后这哥们儿马不停蹄又问了xx系的办公室主任助理同学,助理同学说是xx系yy班的,然后很仗义的哥们儿去xx系yy班的班长那里取到了该女孩儿电话。(此处完成若干次迭代查询,即,问询者角色不变,但反复更替问询对象)最后,他把号码交到了你手里。完成整个查询过程。

通过上面的步骤,我们最后获取的是IP地址,也就是浏览器最后发起请求的时候是基于IP来和服务器做信息交互的。

HTTP协议详解

HTTP协议是Web工作的核心,所以要了解清楚Web的工作方式就需要详细的了解清楚HTTP是怎么样工作的。

HTTP是一种让Web服务器与浏览器(客户端)通过Internet发送与接收数据的协议,它建立在TCP协议之上,一般采用TCP的80端口。它是一个请求、响应协议–客户端发出一个请求,服务器响应这个请求。在HTTP中,客户端总是通过建立一个连接与发送一个HTTP请求来发起一个事务。服务器不能主动去与客户端联系,也不能给客户端发出一个回调连接。客户端与服务器端都可以提前中断一个连接。例如,当浏览器下载一个文件时,你可以通过点击“停止”键来中断文件的下载,关闭与服务器的HTTP连接。

HTTP协议是无状态的,同一个客户端的这次请求和上次请求是没有对应关系的,对HTTP服务器来说,它并不知道这两个请求是否来自同一个客户端。为了解决这个问题, Web程序引入了Cookie机制来维护连接的可持续状态。

HTTP协议是建立在TCP协议之上的,因此TCP攻击一样会影响HTTP的通讯,例如比较常见的一些攻击:SYN Flood是当前最流行的DoS(拒绝服务攻击)与DdoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式。

HTTP请求包(浏览器信息)

我们先来看看Request包的结构, Request包分为3部分,第一部分叫Request line(请求行), 第二部分叫Request header(请求头),第三部分是body(主体)。header和body之间有个空行,请求包的例子所示:

GET /domains/example/ HTTP/1.1		//请求行: 请求方法 请求URI HTTP协议/协议版本
Host:www.iana.org				//服务端的主机名
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4			//浏览器信息
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8	//客户端能接收的MIME
Accept-Encoding:gzip,deflate,sdch		//是否支持流压缩
Accept-Charset:UTF-8,*;q=0.5		//客户端字符编码集
//空行,用于分割请求头和消息体
//消息体,请求资源参数,例如POST传递的参数

HTTP协议定义了很多与服务器交互的请求方法,最基本的有4种,分别是GET,POST,PUT,DELETE。一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查,增,改,删4个操作。我们最常见的就是GET和POST了。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。

通过fiddler抓包可以看到如下请求信息:

在这里插入图片描述

图3.4 fiddler抓取的GET信息

在这里插入图片描述

图3.5 fiddler抓取的POST信息

我们看看GET和POST的区别:

  1. 我们可以看到GET请求消息体为空,POST请求带有消息体。
  2. GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456。POST方法是把提交的数据放在HTTP包的body中。
  3. GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制。
  4. GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码。

HTTP响应包(服务器信息)

我们再来看看HTTP的response包,他的结构如下:

HTTP/1.1 200 OK						//状态行
Server: nginx/1.0.8					//服务器使用的WEB软件名及版本
Date:Date: Tue, 30 Oct 2012 04:14:25 GMT		//发送时间
Content-Type: text/html				//服务器发送信息的类型
Transfer-Encoding: chunked			//表示发送HTTP包是分段发的
Connection: keep-alive				//保持连接状态
Content-Length: 90					//主体内容长度
//空行 用来分割消息头和主体
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... //消息体

Response包中的第一行叫做状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。

状态码用来告诉HTTP客户端,HTTP服务器是否产生了预期的Response。HTTP/1.1协议中定义了5类状态码, 状态码由三位数字组成,第一个数字定义了响应的类别

  • 1XX 提示信息 - 表示请求已被成功接收,继续处理
  • 2XX 成功 - 表示请求已被成功接收,理解,接受
  • 3XX 重定向 - 要完成请求必须进行更进一步的处理
  • 4XX 客户端错误 - 请求有语法错误或请求无法实现
  • 5XX 服务器端错误 - 服务器未能实现合法的请求

我们看下面这个图展示了详细的返回信息,左边可以看到有很多的资源返回码,200是常用的,表示正常信息,302表示跳转。response header里面展示了详细的信息。

在这里插入图片描述

图3.6 访问一次网站的全部请求信息

HTTP协议是无状态的和Connection: keep-alive的区别

无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。

HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(面对无连接)。

从HTTP/1.1起,默认都开启了Keep-Alive保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的TCP连接。

Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同服务器软件(如Apache)中设置这个时间。

请求实例

在这里插入图片描述

图3.7 一次请求的request和response

上面这张图我们可以了解到整个的通讯过程,同时细心的读者是否注意到了一点,一个URL请求但是左边栏里面为什么会有那么多的资源请求(这些都是静态文件,go对于静态文件有专门的处理方式)。

这个就是浏览器的一个功能,第一次请求url,服务器端返回的是html页面,然后浏览器开始渲染HTML:当解析到HTML DOM里面的图片连接,css脚本和js脚本的链接,浏览器就会自动发起一个请求静态资源的HTTP请求,获取相对应的静态资源,然后浏览器就会渲染出来,最终将所有资源整合、渲染,完整展现在我们面前的屏幕上。

网页优化方面有一项措施是减少HTTP请求次数,就是把尽量多的css和js资源合并在一起,目的是尽量减少网页请求静态资源的次数,提高网页加载速度,同时减缓服务器的压力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/149967.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt中使用QNetworkAccessManager类发送https请求时状态码返回0

前言 在项目开发中&#xff0c;碰到一个问题&#xff0c;使用QNetworkAccessManager类对象发送https请求时&#xff0c;状态码一直返回0&#xff0c;抓包分析看请求响应也是正常的。费了好大劲终于搞定了&#xff0c;主要是两个原因导致的。 原因一&#xff1a;未设置支持SSL…

cookie 和 session的区别(简单易懂)

cookie&#xff1a; Cookie是访问某些网站以后在本地存储的一些网站相关的信息&#xff0c;下次再访问的时候减少一些步骤。 浏览器端第一次发送请求到服务器端&#xff0c;服务器端创建Cookie&#xff0c;该Cookie中包含用户的信息&#xff0c;然后将该Cookie发送到浏览器端&…

基于RK3588的8k多屏异显安卓智能网络机顶盒

采用RK3588芯片方案的8K网络机顶盒&#xff0c;搭载纯净的安卓12操作系统&#xff0c;支持Ubuntu和Debian系统容拓展。主要面向外贸市场。此款机顶盒自带两个HDMI输出接口&#xff0c;一个HDMI输入接口&#xff0c;内置双频WiFi6无线模块&#xff0c;支持千兆以太网和USB接口。…

【文末送书】十大排序算法及C++代码实现

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

微创机器人:CRM撬动售后服务数字化升级

一方面&#xff0c;我国医疗器械行业起步较晚&#xff0c;更注重产品的销售和业务的拓展&#xff0c;企业售后服务整体比较滞后。 另一方面&#xff0c;医疗器械售后服务环节数字化程度不足&#xff0c;一些企业仍通过传统的线下手段管理售后服务&#xff0c;进行数字化尝试的…

【快速解决】实验四 对话框 《Android程序设计》实验报告

目录 前言 实验要求 实验四 对话框 正文开始 第一步建立项目 第二步选择empty views activity点击next ​编辑 第三步起名字&#xff0c;点击finish 第四步对 activity _main.xml文件操作进行布局 第五步&#xff0c;建立两个新文件&#xff0c;建立方法如下 SecondA…

npm报错

npm报错 npm ERR! Fix the upstream dependency conflict, or retry npm ERR! this command with --force or --legacy-peer-deps npm ERR! to accept an incorrect (and potentially broken) dependency resolution. npm ERR! npm ERR! npm ERR! For a full report s…

16. Spring源码篇之指定构造方法参数

简介 为什么讲这个&#xff0c;是因为在spring使用构造方法注入的时候会有大量的判断&#xff0c;是不是指定了参数。如果指定了参数就可以使用不同的构造方法去实例化Bean&#xff0c;本文将介绍如何指定参数 使用 首先看一个例子 // 定义三个构造函数 public class UserB…

SLAM中提到的相机位姿到底指什么?

不小心又绕进去了&#xff0c;所以掰一下。 以我个人最直观的理解&#xff0c;假设无旋转&#xff0c;相机在世界坐标系的(5,0,0)^T的位置上&#xff0c;所谓“位姿”&#xff0c;应该反映相机的位置&#xff0c;所以相机位姿应该如下&#xff1a; Eigen::Matrix4d T Eigen::M…

Linux gdb调试的时候没有对应的c调试信息库怎么办?

gdb 调试报错&#xff1a;Missing separate debuginfos, use: debuginfo-install glibc-2.17-260.el7_6.6.x86_64 在centos7上面gdb调试程序时候&#xff0c;报错信息是&#xff1a; Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7_3.5.x86_64 解决…

Redis学习笔记14:基于spring data redis及lua脚本ZSET有序集合实现环形结构案例及lua脚本如何发送到redis服务器

案例实现目标&#xff0c;一、实现一个环形结构&#xff0c;环形结构上节点有一个阀值threshold,超过阀值则移除分数score最低的成员&#xff0c;不足则将当前成员添加进环中&#xff0c;且确保成员不可重复&#xff1b;二、每次访问环中的数据都需要刷新key的过期时间&#xf…

亚马逊云科技AI创新应用下的托管在AWS上的数据可视化工具—— Amazon QuickSight

目录 Amazon QuickSight简介 Amazon QuickSight的独特之处 Amazon QuickSight注册 Amazon QuickSight使用 Redshift和Amazon QuickSightt平台构建数据可视化应用程序 构建数据仓库 数据可视化 Amazon QuickSight简介 亚马逊QuickSight是一项可用于交付的云级商业智能 (BI…

基于circle group的Reed-Solomon codes

1. 引言 Polygon团队Ulrich Habock等人2023年论文 Reed-Solomon codes over the circle group。 前序博客有&#xff1a; Plonky3 Mersenne素数域的Reed-Solomon codes设计 STARKs支持任意size的域&#xff0c;而不要求是椭圆曲线。STARKs中在选择域size时&#xff0c;越小…

Unity中 Start和Awake的区别

Awake和Start在Unity中都是MonoBehaviour脚本中的生命周期函数 Awake函数在游戏对象首次被加载时调用&#xff0c;在游戏对象初始化之前调用。 start函数在游戏对象初始化完成后调用&#xff0c;在update第一次执行前调用。 这两个函数在其生命周期内都只会调用一次&#xf…

替换sql,某个字段特定容

要替换wp_posts表中的wp_posts.post_content字段中的特定文本&#xff0c;可以使用MySQL的UPDATE语句和字符串替换函数来实现。 sql&#xff1a;语句 UPDATE 表名 SET 字段名 REPLACE(字段名, 原本内容, 替换内容);请注意&#xff0c;执行这样的操作可能会对数据库产生较大的…

verilog语言中条件编译ifdef的使用和例子

1条件编译ifdef 如果ifdef后面的参数被编译过&#xff0c;则编译ifdef语句后的内容&#xff0c;忽略else后面的内容&#xff0c;如果ifdef后面的参数没有被编译过&#xff0c;则编译else语句后面的内容&#xff0c;条件编译的范围以ifdef开始&#xff0c;以endif结束&#xff…

Android studio访问选程https接口(.crt handshake)

如果服务器是https的&#xff0c;访问受限怎么办&#xff1f;有两种方法&#xff0c;一种是接受一切证书个人官方正式非正式&#xff0c;当然这样就牺牲了安全性&#xff0c;网上方法很多&#xff0c;我现在教大家如何去验证crt文件 首先服务器是https的&#xff0c;必然有几个…

js数组操作——对象数组根据某个相同的字段分组

js数组操作——对象数组根据某个相同的字段分组 可以使用JavaScript的map()方法和reduce()方法来实现将数组中包含的数组对象的某个字段整合为数组的操作。具体实现方法如下&#xff1a; 假设有以下数组对象arr&#xff1a;let arr [{name: Tom, age: 18, hobbies: [reading,…

SpringBoot的启动流程

一、SpringBoot是什么&#xff1f; springboot是依赖于spring的&#xff0c;比起spring&#xff0c;除了拥有spring的全部功能以外&#xff0c;springboot无需繁琐的xml配置&#xff0c;这取决于它自身强大的自动装配功能&#xff1b;并且自身已嵌入Tomcat、Jetty等web容器&am…

redis+python 建立免费http-ip代理池;验证+留接口

前言: 效果图: 对于网络上的一些免费代理ip,http的有效性还是不错的;但是,https的可谓是凤毛菱角; 正巧,有一个web可以用http访问,于是我就想到不如直接拿着免费的HTTP代理去做这个! 思路: 1.单页获取ipporttime (获取time主要是为了后面使用的时候,依照时效可以做文章) 2.整…