Web网站开发----Http协议&Tomcat服务器

一. HTTP协议

1.1 HTTP是什么

HTTP("超文本传输协议"),是一种广泛使用的"应用层协议".

"超文本"是指传输的内容不仅仅是文本,还可以传输其他类型的数据(比如音频,图片等).     

 目前市面上已经有了多个HTTP版本,其中最主流的还是HTTP1.1,它是基于传输层的TCP协议实现的.

为啥开发一个网站要先了解HTTP呢?我们通过浏览器访问一个网站,就是基于HTTP实现的.

  • 浏览器和服务器之间也是C/S模型,浏览器发送一个请求,百度服务器就会返回一组数据给浏览器(上图中的页面就是返回数据的一部分)

1.2 细看"应用层协议"

前面只是简单地提到过,应用层协议是专门为某一应用服务的.

在座的各位可能不太懂这句话的含义(说实话,它是挺抽象的),那就让我们一起抓个包,借助HTTP协议体会这句话吧!

1.2.1 Fiddler的使用

网上的抓包工具有很多,在这里博主就用Fiddler了.安装好Fiddler后,出现下面的界面

左侧页面显示的是主机上所有的HTTP请求/响应,选中某条数据即可在右侧查看具体内容.

如上图,我选中的是访问baidu后时发起的请求,但是右侧页面的内容显然看不懂...

上图的按键可以帮助我们看到HTTP协议的具体格式.

其中上半部分是我们本地的浏览器发起的请求,下半部分是百度服务器返回的响应.

在这里解释两个小问题:

1. 为啥响应一开始是二进制数据? ---- 网络通信上,最珍贵的就是带宽,为了节省资源,就会把文本数据压缩成二进制传输.具体是如何压缩的,此处不进行过多讨论.

2. 为啥上图中没有http,只有https? ----https实际上是"安全版"的http,二者的区别后文还会涉及,请耐心观看吧~

1.2.2 抓包工具的原理

Fiddler相当于一个"代理".

当我们的浏览器向百度服务器发送请求的时候,会把http请求发给Fiddler,然后Fiddler交给百度服务器;当百度服务器返回数据的时候,也会先把响应发给Fiddler,然后由Fiddler转交给我们的浏览器.

所以Fiddler对客户端/服务器之间的交互细节一清二楚.

实际上,代理又分"正向代理"和"反向代理".正向代理是代理的客户端;反向代理代理的是服务器.

举个栗子~滑稽老铁在家烧的厉害,就找了个跑腿帮他去买药,那么这个跑腿就是正向代理;恰好药店的老板干饭去了,就给让他儿子几号柜台拿XXX药,老板儿子就是反向代理.

1.3 HTTP请求

有了抓包工具,我们就很清晰的看到浏览器向服务器发送的请求.分为四部分: 首行+报头+空行+正文

1.3.1 认识URL

下图就是请求的首行=方法名+URL(唯一资源定位符)+http版本号

先来看URL吧,它是最重要的一部分.

"URL"是唯一资源定位符,可以帮助我们访问到网络上的某一资源."URI"是唯一资源标识符,它的范围更大,URL是URI实现的一种方式.

 一个具体的URL由以下几部分组成:

  1. https,协议方案名.常见的是http和https,也有其他类型(比如访问MySQL使用的jdbc:mysql).
  2. cn.bing.com,服务器地址.一般使用域名/IP地址表示.
  3. 端口号,表示访问的是服务器上的哪个端口.上图中URL的端口号都被省略了,http协议默认使用80端口,https默认使用443端口.
  4. /search:表示要访问的文件资源路径.如果这部分只有"/",默认访问服务器根目录.
  5. 查询字符串: 以?开头,使用key=value的形式表示,各个键值对之间以&分隔(可省略)
  6. 片段标识符: 以#开头,主要用于页面跳转(在访问文档时比较常见,用于标识文档的某一部分内容)(可省略)

查询字符串需要进行URLencode编码处理

比如博主想搜索JDK,URL中的查询字符串如下

像/ ?这样的字符,在URL中有着特殊的含义,因此这些字符不能随意出现.当用户输入的参数中包含这些字符时,就要进行转义.

就好像我们想打印出来一个" \",但是并不能直接打印出来,需要借助'\'转义字符完成.

我们可以使用 ping 命令查看域名对应的IP地址,以及丢包情况.

1.3.2 请求方法

http协议提供了多种请求方法:

方法说明支持的http版本
GET获取资源1.0,1.1
POST传输实体主体1.0,1.1
PUT 传输文件1.0,1.1
HEAD获得报文首部1.0,1.1
DELETE删除文件1.0,1.1
OPTIONS询问支持的方法1.1
TRACE追踪路径1.1
CONNECT要求用隧道协议连接代理1.1
LINK建立和资源之间的联系1.0
UNLINK断开连接关系1.0

别看方法这么多,根据二八定律,我们只要熟悉get/post方法即可.

1.3.2.1 GET方法

GET方法是请求常用的一个方法,用来获取服务器上的某个资源

来看一个get请求

  • GET请求往往没有body
  • GET请求传递的信息一般出现在QueryString中
  • header的格式为key:value结构,每个键值对占一行
  • GET实际上是有空行的
1.3.2.2 POST方法

POST方法多用于用户向服务器提交信息(比如上传图片等)

上图是博主向学校登陆学校某个实验平台的请求.

  • POST的QueryString往往为空(也可以不为空)
  •  POST往往将传递信息放在body里
  • POST的body一般不为空
  • body的长度和格式分别由header中的Content-length和Content-Type指定

浅谈一下GET和POST的区别:

1. GET一般用于获取数据,PUT一般用于提交数据.

2. GET请求的信息一般放在QueryString中,body部分为空;PUT请求的信息一般放在body中,QueryString为空.

3. GET请求一般是幂等的(相同的请求得到相同的响应),PUT请求一般是不幂等的.

4. GET得到的数据可以被缓存(请求的结果保存在本地),PUT通常不能缓存

GET和PUT方法本质上是相同的,二者可以相互替换.(get也可以使用body传送数据,put亦可以将数据存放在QueryString中,这要看开发者的定义)

"put方法要比get安全,因为put将数据放在了body中,用户无法直接看到",实际上是一种谬论----博主使用抓包工具就可以得到body,根本没有安全性可言!

"put方法传递的数据更多",这也是一个错误观点.标准文档上并没有规定这两种方法的数据传输量,只是一些浏览器将它们区分开了而已.

1.3.3 认识报头

header的整体格式也是键值对结构.每个键值对独占一行,键和值之间用" : "分割

下面介绍几个比较重要的键值对.

1. Host:表示最终访问的服务器主机的主机地址和端口(大概率下与首行的URL相同).

2. Content-Length: 表示body中的数据长度(get请求通常没有这个属性).

3. Content-Type: 表示请求中的Body的数据格式(get请求中通常没有这个属性).

还记得基于TCP传输的"粘包问题"吗?由于是面向字节流传输,应用层协议无法区分哪些字节代表哪些含义,2和3键值对就可以帮助区分正文部分

 4. User-Agent: 表示浏览器和操作系统的属性.

早期的浏览器就相当于"电子版报纸",只支持文本的显示,后来的新版本浏览器开始陆续支持图片,音频等. 但是产生了兼容性问题----如果客户端使用的旧版本浏览器,网站发布的超文本信息就没法看到,并且还会产生不好的体验.

为了解决这个问题,发布者干脆制作两种类型的页面,然后根据客户端浏览器的版本判断传输哪种类型,因此这个属性在以前还是很有必要的.

现在主要用来区分PC端还是移动端,以适应窗口大小.

 5. Referer: 表示这个页面是从哪个页面跳转过来的.

老铁们肯定都在浏览器上看见过这样的广告.

如果我使用的是搜狗浏览器,然后搜索"鲜花预定",接着找一个广告点进去,抓一下包.

 就可以看到Referer上有着不可忽视的sogou,这就表明我为搜狗多送了一份money~

如果有商家与某个搜索引擎的服务商有商业合作,他们之间的交易额是通过在这个引擎上点击广告的次数来衡量的.商家和sogou都会有一个日志文件,专门记录一共有客户端多少次访问.

但是使用http有一个问题----http是使用明文(没有加密的内容)传输的,可以随便修改,网络的接入都是由运营商提供的,这时候运营商就可以把Referer修改成自己名下的广告平台,这一做法称为"运营商劫持".

6. Cookie

出于安全性考虑,浏览器本身并不能访问计算机硬盘,但是客户端这边往往需要存储一些数据.于是硬盘上就专门开辟了一块空间,用来存储从服务器那边返回的数据,这部分数据就是"Cookie".

Cookie的存储按照域名划分.

比如点击Bing浏览器上的小锁,就可以看到这网站的Cookie了

Cookie保存的内容和含义是由服务器开发人员指定的,下图是CSDN网站上的某一Cookie,包括创建时间,过期时间等.

 Session----Cookie中用来表示用户身份信息的键值对,是Cookie中最重要的键值对!!!

下面来讲一下Session机制

1> 当我们第一次登陆/访问一个网站,服务器会给我们安排一个"身份证"(Session-id),同时会创建一份"电子档案"(session)保存我们的信息.

2>  这个身份标识会被保存在本地的Cookie中,当我们下次再访问这个网站的时候,会把它交给服务器,这个服务器就会根据这张卡查询到用户的全部信息.


来捋一下思路:

当我们访问一个网站时,服务器返回的响应中会有一些数据.一部分数据就会被保存在本地硬盘上,称为"Cookie".

Session是Cookie中的键值对之一,当我们首次访问一个网站时,服务器会建立一份档案记录用户信息,同时给这份档案一个编号,然后把这个编号返回给客户端;当我们再次访问这个网站时,会自动在请求中带上这个编号,服务器就可以通过这个编号了解到我们的信息(上次的浏览历史,视频观看进度等)

1.3.4 认识正文

正文的格式和长度与Content-Type和Content-Length密切相关.

 常见的请求格式有以下几种:

appliction/x-www-form-urlencoded: 使用form表单格式提交的数据采用的格式.

application/json:  数据格式为json格式.

multipart/form-data: form表单提交的数据格式(通常用于提交图片/文件)

1.4 HTTP响应

下图为sogou的响应

可以看到,响应首行格式=协议版本+状态码(+状态描述) 

1.4.1 认识"状态码"

状态码表示访问一个页面的结果(访问成功,失败,受限...)

响应一共分为五大类:

状态码范围类型
100~199信息响应
100 Continue表示访问可行,客户端继续等待即可

200~299响应成功
200 OK响应成功

300~399重定向消息
302 Found临时重定向
301 Move Permanently永久重定向

400~499客户端出错
404 Not Found没有找到要访问的资源
403 Forbidden用户没有权限访问
405 Method Not Allowed服务器无法处理客户端使用的请求方法

500~599服务器出错
500  Internal Server Error服务器遇到了无法处理的情况
504 Gateway Timeout某一服务器充当网关,需要接收应用服务器传来的响应,如果响应超时,就会返回这个状态码

关于"重定向",可以借助下面一个例子来理解~

滑稽老铁开了个饭馆,专门卖"锅包肉"~招揽了很多顾客.

房主把房租涨了100块钱,滑稽老铁觉得太贵,决定换个地方,于是在原来的旧地址上留下一张字条

 

原先的熟客们看到字条,就会主动去新地址找滑稽老铁~ 

302表示用户请求资源的URL已经暂时更改,当客户端使用这个URL访问时,服务器会自动访问新的URL(当老顾客来到旧店面时,会有一辆车把他们拉到新店铺前)

301表示用户请求资源的URL已经永久更改,后续浏览器再使用旧的URL,会被自动改成新的URL

1.4.2 响应报头/正文

响应的报头和请求是一样的,此处不再做过多讨论.

响应的正文部分往往类型更多,下面列举出一小部分:

 

 1.5 构造HTTP请求

1.5.1 通过form表单构造请求

通过form表单,我们只能使用get/post方法发送请求.

下面是用html写的一个提交页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="https://www.sogou.com" method="get"> //提交到action里的url中,方法是get
        <input type="text" name="name">//QueryString里的key为name,value为用户输入的值
        <input type="text" name="id">//QueryString里的key为id,value为用户输入的值
        <button id="submit">提交</button>//点击这个按钮会提交请求
    </form>
</body>
</html>

点击提交,我们可以用Fiddler抓包观察提交的请求

也可以将method对应的value改为post,然后抓包观察一下

 可以看到,使用form表单提交数据时,正文格式为application/x-www-form-urlencoded类型,这种类型实际上就是QueryString的编码方式.

1.5.2 通过ajax构造请求

ajax全称Asynchronous Javascript And XML,是一种使用JavaScript给服务器发送请求的一种方式.

ajax的特点是异步的,当我们使用ajax提交请求时,即使服务器没有返回响应,浏览器这边的代码也可以继续执行.

我们需要借助第三方库jquery引入ajax,在浏览器上搜索jquery cdn(是大佬们搞出来的服务器,专门用来存放各种常用资源)

博主打开的是bootcdn仓库,复制上面的script标签,然后放到自己的html文件上即可

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
    <script>
        $.ajax({//$是一个特殊的全局对象,jquery的api都是用$.方法的形式使用的
            url:"https://www.sogou.com",//服务器的URL
            type:"get",//使用的方法
            success: function(data){//data是服务器返回响应的数据
                console.log(ok);
            }
        });
    </script>
</body>
</html>

下图是抓的包

虽然这次搜狗的服务器返回了数据,但是不会直接显示在我们的浏览器上.需要使用前端语言将接受的数据呈现在页面上,此处不再展开.

1.5.3 使用Java Socket构造请求

根据TCP/IP模型,HTTP请求在进行封装的时候一定会经过数据链路层,我们可以按照HTTP协议的格式"伪造"一个应用层数据包,然后把它交给数据链路层传输即可.

因为代码比较冗余,博主不再演示...

1.5.4 使用第三方工具

博主使用的是PostMan来帮助发送请求

第一次使用的时候需要先点击WorkSpaces,然后点击+号

 如下图,PostMan可以多种方法帮助我们构造请求,具体的使用读者们自己去探索吧

1.6 什么是HTTPS

HTTPS也是一个应用层协议,在HTTP协议的基础上引入了加密层.

HTTP协议内容都是按照文本的方式明文传输的,这就导致在传输过程中出现一些数据被篡改的情况.

 1.6.1 运营商劫持

其实在前文讲到Header中的"Referer"部分时我们已经谈及过这个问题,不妨再举个栗子~

不知道同学们对下面这个应用是否熟悉~反正博主对它很是反感,前几年,每次从浏览器上下载一些文件,都会自动跳转到这个应用的下载,这也是因为"运营商劫持".

于是就有了HTTPS,使用加密来保证用户信息的安全.

1.6.2 什么是"加密"

  • 加密就是把明文(要传输的信息)进行一系列变换,生成密文.
  • 解密就是把密文进行一系列变换,还原成明文.
  • 在加密和解密的过程中,往往需要借助另外的数据辅助进行,这样的数据称为"密钥".

 诸位经常看宫斗戏的老表应该都知道,后宫的娘娘倍感孤独时,用熬煮的米汤写下自己的思念,宫外的情郎将信浸入海带的煮出液中(含碘),就会显现出字迹.

"明文"就是娘娘要传的话,"密文"就是米汤干后的透明痕迹,"米汤"就是加密的密钥,"海带汤"就是解密的密钥.

如果加密和解密使用的是同一个密钥,称为"对称加密",反之称为"非对称加密".

1.6.3 HTTPS的加密过程

由于对称加密的效率要比非对称加密高的多,因此HTTPS使用对称加密的方式传递数据.

下图为客户端/服务器交互过程的演示

机智的老铁们肯定一眼就看出了问题----如果在传输密钥的时候被有心人看到了,C/S传输的数据不就彻底暴露了嘛~

于是采用非对称加密的方式运送对称加密的秘钥.

服务器拿到对称加密的秘钥后,后续C/S仍用对称加密的方式传输数据.

这种方式乍一看是不是没有问题?但是如果在中间插上一个黑客,就有大大的问题了.

如上图,拿到client端传来的对称密钥后,后续C/S的交互不就暴露在黑客眼皮子底下了么!

 


于是正儿八经的解决方案来了~为了防止黑客充当"中间人",引入了第三方机构 

每个正规网站都会向第三方的公证机构提交资质,申请一份证书.

如下图,为某网站证书的部分信息.

 认证机构自己有一对非对称秘钥,该机构用一定的算法对服务器的信息计算得到哈希值,然后用私钥加密生成签名,信任该机构的客户端(主机)在出厂设置时都会在本地保存这个机构的公钥.

1. 当客户端与服务器建立连接的时候,服务器会发给客户端一份证书,这份证书上包含服务器生成的公钥和服务器的相关信息.

2. 客户端拿到证书后,会用本地的公钥对证书的签名解密,然后使用证书上的算法对其他信息进行计算,如果二者相同,证明这个证书是服务器发过来的.

3. 客户端使用证书上的公钥对请求加密.

肯定有童鞋还在懵逼的状态.下面提出两个假设助于理解~

服务器将证书发给客户端时>>如果有黑客将证书上的公钥修改成自己的,客户端对签名解密然后对照哈希值时,出现不一致,浏览器会拒绝访问.

客户端将加密后的请求(包含公共密钥)发给服务器时>>如果有黑客想要知道公共密钥,但是因为没有服务器的私钥,所以无法解密.


实际上,道高一尺魔高一丈.黑客也可以伪装成认证机构,只要骗客户端安装自己的公钥,同样可以获得C/S的交互信息.

二. Tomcat

2.1 什么是Tomcat

此Tomcat并非动漫界的汤姆猫,而是一个"HTTP服务器",用来运行多个网站.

Apache最早也是一个开源的http服务器(但是不支持java进行后端开发),后来影响力变大,形成了一个开源社区,Tomcat就是其中的开源产品之一.(Tomcat本身就是java写的,支持java开发)

2.2 认识Tomcat

2.2.1 Tomcat的安装

Tomcat安装官网

 童鞋们可以直接到官网上安装,博主安装的是Tomcat 8,Tomcat的版本对应相应的servlet(Tomcat提供的api,用来操作http服务器)

进入官网后,直接点击压缩包即可下载.

 2.2.2 Tomcat的文件目录

下图为Tomcat解压后的目录

1. bin/,二进制脚本(与剧组中的脚本功能是一样的,用来指导下一个镜头/动作怎么做), 是多个命令的组合

进入bin目录,就会看到两个startup脚本,linux/mac系统点击*.sh(shell脚本),Windows系统点击*.bat(批处理脚本),就可以运行Tomcat了

 然后就会弹出一个命令框,出现上图中标红的语句就表示Tomcat运行成功

接下来我们使用浏览器访问 127.0.0.1:8080,就会出现Tomcat页面,用于验证Tomcat启动成功

2. conf/,用来存放Tomcat的配置文件,其中server.xml是服务器的配置文件(包含启动端口等信息)

3. logs/ ,我们有时候需要查看运行日志,来定位一些问题,这个目录就存放日志文件

4.  webapps/ ,Tomcat可以运行多个网站,每个网站都是一个webapp,存放在webapps目录下

比如我们刚才访问http://127.0.0.1:8080/,实际上访问的就是webapps目录下的根目录(这也就和上文学习的url结合起来了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不 会敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值