JavaWeb--HTTP协议(下)

前言

这一部分就是HTTP协议的下办部分。笔者可能有些地方总结的不是很到位,所以哪里有问题或者说有缺漏还是希望各位读者朋友能够指出。一丶二丶三在上一篇博客,链接放在下面。
HTTP协议(上)

四丶HTTP响应详解

前面说了关于HTTP请求的相关问题,这里阐述HTTP响应的相关问题。
具体的还是用一张图来进行表示。
在这里插入图片描述

认识响应状态码

状态码是由三位数字构成,标识服务端对客户端这次请求的处理结果。HTTP响应报文,都是由服务端返回的(程序可以设置内容),状态码也可以由程序设置。

1>200

200标识服务端对当次请求处理成功。如果说程序有bug,当出现异常的时候,本应
该返回表示处理失败的500状态码,但是实际上却返回了200,就需要程序员去检查后端代码逻辑。

2>404

404 Not Found:标识请求的url路径,没有对应的资源。
url格式是:[协议名]://[ip或者域名]:[port]/[带层次的路径]?[查询字符串]
所以这里的404 Not Found就是[带层次的路径]在进程当中找不到。

3>304

304 Not Modified:表示之前已经访问过的资源,本次请求的时候,没有被修改过
如果返回304,就代表客户端可以直接从缓存当中获取。如果需要抓包看到真实的
内容,可以ctrl+f5进行刷新。

(1)客户端输入一个url,有时候,会直接从缓存当中获取,而不会发送该
url的http数据包
(2)服务端返回304,客户端也会从缓存中获取。

4>403

403 Forbidden:禁止访问。一般是访问权限不足,返回处理的结果:(1)未登录
就去访问 (2)登录后,权限不足

5>405

405 Method Not Allowed:方法不支持。
1.在服务端提供某个url资源服务的时候,其方法,可以是一个或者多个(比如GET
,POST)。如果客户端请求的时候,请求方法不在服务端提供的方法范围之内(比
如我服务端就只能提供PUT),这个时候就会返回405。
2.如果出现405状态码,要检查是前端请求方法不对(就像上边一样,前端请求方
法改为GET或者POST),还是后端提供的方法不对(像上边一样,后端提供的服务
方法,也要提供POST方法)。

注意:前后端方法使用要相同!!!

6>500

500 Internal Server Error:服务器内部错误。一般就是服务器的内部代码有问
题,如果出现500状态码,就要去检查后端控制台异常的堆栈信息,然后定位后端的代码问题。

7>504

504  Gateway Timeout:请求在服务端处理超时。服务端也有返回响应时间的限
制(这里可以在服务端设置),发现处理时间超过这个时间就返回504。
关于服务端时间限制:如果不设置时间限制,那么服务端就会一直运行
关于处理时间超时:这里造成这种情况的原因可能有请求很多(高并发),程序处
理不过来,还可能是程序效率低。
关于客户端请求时间限制:没错,客户端请求也是有时间限制的(JS代码当中可以
设置),如果服务端没有在规定时间内返回,那么也会报错(当然也会执行JS中
代码定义的方法)。

8>302 && 301

301:永久重定向
302:临时重定向
这里两个效果看起来都一样,但是临时和永久的区别就是看服务端某个资源是临时
改变,之后会改回,还是永久就改变了。

对于重定向来说

(1)会发送两次请求
(2)url会发生改变:第一次请求的url,会变为第一次响应Location当中的地址。

在这里插入图片描述
注意这个过程当中发生的改变。

9>总结

1xxx:接收的请求正在处理。如使用websocket,需要提前准备连接,先返回1xx。
2xxx:请求正常处理完毕。
3xxx:需要进行附加操作以完成请求。301,302,307重定向
4xxx:服务器无法处理请求。你(客户端)出错了
5xxx:服务器处理请求出错。我(服务端)出错了

附:HTTP知识点小结

格式总结

在这里插入图片描述

这里再给出关于Content-Type和body的常用数据格式:
(1)表单格式:键=值 & 键=值
(2)form-data格式:多个字段,每个字段可以是复杂类型。
(3)application/json:和js中json对象格式一样。
(4)html,jss,css
(5)图片,视频等等

关于cookie和session的区别

1>存储位置不同:cookie在客户端浏览器,session在服务端
2>存储容量不同:一个cookie数据<=4kb,最多保存20个。但是session没有这个限制,虽然是没有限制,但是为了性能,session最好设置一个删除机制。
3>存储方式不同:cookie只能保存ascall码,并且存储方式为二进制数据或者Unicode字符。而Session能够保存任意类型数据。
4>隐私策略不同:cookie对客户端可见,所以不安全。session存储在服务器上,对客户端不可见,所以是安全的。
5>有效期不同:cookie可以通过设置长期有效,但是session依赖于sessionid,而cook sessionid过期默认时间是-1,所以关闭该窗口的时候session就会过期。
6>服务器压力不同:cookie保管在客户端,不占用服务器资源。但是session是保管在服务器端的,每个用户都会产生一个session,当用户多的时候,就会消耗大量的资源。
7>跨域不同:cookie支持跨域名访问,但是session不行。

关于网络安全问题

D N S 劫 持 \color{red}{DNS劫持} DNS

域名转IP是基于DNS协议,一个树形结构(每一个节点都是一个域名DNS服务器,或者DNS缓存)中,从下到上来查询域名对应的ip,用户在不同的地方(如省市)就可能使用不同的DNS服务器。DNS劫持就是把我们域名对应的IP换为它希望的一个IP。

H T T P 劫 持 \color{red}{HTTP劫持} HTTP

HTTP是明文传输,所以传输过程当中,就完全有可能被黑客劫持,并且篡改内容。

五丶通过form表单构造HTTP请求

form(表单)是HTML中的的一个常见标签。可以給服务器发送GET或者POST请求,在form标签当中

1.action:是请求的url
2.method:是请求的方法
3.get方法默认请求数据在queryString上,post方法默认放在body上
4.post默认提交方式(Content-Type)是表单格式提交(application/x-www-
form-urlencoded)

对于input标签

type: 表示输入框的类型. text 表示文本, password 表示密码, submit 表示提
交按钮。
name: 表示构造出的 HTTP 请求的 query string的key.query string的value就
是输入框的用户输入的内容. 
value: input 标签的值. 对于 type 为submit 类型来说, value 就对应了按钮
上显示的文本. 

<1>form发送GET请求

<body>
    <form action="http://abc.com" method="get">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="提交">
    </form>
</body>

这里的name相当于queryString的key,而input输入的内容就相当于queryString的value。

<2>form发送POST请求

<body>
    <form action="http://abc.com" method="post">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="提交">
    </form>
</body>

和GET请求的区别

1.method从GET变为了POST
2.数据从queryString移动到了body

六丶通过ajax构造HTTP请求

首先为什么会有ajax提交技术呢?
在我们前端html,表单格式提交数据的时候,url也会改变,所以页面也会进行刷新或者跳转。但是如果说我们只是想改变页面的局部内容的时候,html还是这样子,就会浪费很大的资源。如下:
在这里插入图片描述

在这里插入图片描述

<1>发送GET请求

我们通过ajax构造http首先就是要构造一个ajax对象,然后通过这个对象来进行接下里的相关操作。

let xhr = new XMLHttpRequest();

然后设置一个异步回调函数到ajax对象的属性当中。当然,这里只是函数的声明,而不会执行。

xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            //xhr.status属性:响应状态码
            console.log(xhr.status);
            //xhr.responseText属性:响应正文
            console.log(xhr.responseText);
        }
    }

		// xhr.readyState属性:
        // 0: 请求未初始化:还没有发送http请求数据
        // 1: 服务器连接已建立
        // 2: 服务端已接收请求
        // 3: 服务端正在处理请求
        // 4: 客户端已经接收到服务端返回的响应,且响应已就绪

接着使用open方法设置要访问的url,我这里的url是一个教学云服务器

xhr.open("GET","http://42.192.83.143:8089/AjaxMockServer/info");

最后使用send方法发送http请求,也可以设置请求正文(body)数据。

xhr.send();

所以总体代码如下:

<script>
    //XMLHttpRequest对象就是ajax发送请求以及处理响应的对象
    let xhr = new XMLHttpRequest();
    //设置一个异步回调函数到ajax对象的属性当中
    //注意:这里只是函数的声明,不会执行,而是发送http请求,对应的事件发生,才会调用函数
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            console.log(xhr.status);
            console.log(xhr.responseText);
        }
    }
    xhr.open("GET","http://42.192.83.143:8089/AjaxMockServer/info");
    xhr.send();
</script>

这里注意了,如果说我们把这个url中的网址改成其他网址,比如:www.sogou.com。那么就会出现报错
在这里插入图片描述

这里也就是跨域异常,跨域问题在ajax当中是因为响应头没有设置允许跨域的信息,ajax为了安全期间,就会报错。
关于这一点我们目前知道就好,不做过多深入了解。

<2>发送POST请求

对于post请求,就需要先设置body当中的内容

1.先使用setRequestHeader 设置 Content-Type。
2.再通过send的参数设置body内容。

具体步骤和上面的差不多,但是就是两处不一样。一个是设置body内容,另外一个是send()发送请求的时候是使用send(body)这样的方法。
具体代码如下:

 //XMLHttpRequest对象就是ajax发送请求以及处理响应的对象
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            console.log(xhr.status);
            console.log(xhr.responseText);
        }
    }
    xhr.open("POST","http://42.192.83.143:8089/AjaxMockServer/info");
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置请求数据格式/类型
    xhr.send("username=abc&password=123");//send(),send(body)两种方式

<3>封装 ajax方法

这里是把ajax的功能封装为一个函数,以此来方便使用。

首先就是封装一个ajax函数,参数args为一个对象。其属性如下

定义args对象属性如下:
menthod是请求方法
url:请求服务器资源的路径
contentType:表示请求正文的格式
body:请求正文
callback:回调函数,响应客户端接收到响应数据后,调用·

具体代码:

let request = {
        method:"POST",
        url:"http://42.192.83.143:8089/AjaxMockServer/info",
        contentType:"application/x-www-form-urlencoded",
        body:"username=abc&password=123",
        callback:function(status,response){//调用的时候传入了两个参数,对应的参数
            console.log("响应状态码:" + status + ",响应正文:" + response)
        }
    }

然后就是正常流程,创建ajax对象,设置回调函数,但是我们之后的功能就用我们上面封装的ajax函数来进行实现就好,代码如下:

function ajax(args){// var ajax = function(){}
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                args.callback(xhr.status,xhr.body);
            }
        }

然后接下来就是要判断JS对象args的属性Content-type和body是否有正文,以此来决定是否要进行发送内容。

		xhr.open(args.method,args.url);
        //如果args中,contentType属性有内容,就设置Content-Type请求头
        if(args.contentType){//js中,if判断,除了判断boolean值,还可以判断字符串,对象等,有值就是true
            xhr.setRequestHeader("Content-type",args.contentType);
        }
        //如果args中设置了body请求正文,调用send(body)访问
        if(args.body){
            xhr.send(args.body)
        }else{//如果没有设置,调用send()
            xhr.send();
        }

最后再加上调用语句就好了

所以总的代码如下:

<script>
    function ajax(args){// var ajax = function(){}
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                args.callback(xhr.status,xhr.body);
            }
        }
        xhr.open(args.method,args.url);
        //如果args中,contentType属性有内容,就设置Content-Type请求头
        if(args.contentType){//js中,if判断,除了判断boolean值,还可以判断字符串,对象等,有值就是true
            xhr.setRequestHeader("Content-type",args.contentType);
        }
        //如果args中设置了body请求正文,调用send(body)访问
        if(args.body){
            xhr.send(args.body)
        }else{//如果没有设置,调用send()
            xhr.send();
        }
    }
    //调用ajax封装的函数
    let request = {
        method:"POST",
        url:"http://42.192.83.143:8089/AjaxMockServer/info",
        contentType:"application/x-www-form-urlencoded",
        body:"username=abc&password=123",
        callback:function(status,response){//调用的时候传入了两个参数,对应的参数
            console.log("响应状态码:" + status + ",响应正文:" + response)
        }
    }
    ajax(request);
    //ajax函数调用过的json对象参数,也可以不声明,直接传入函数
    // ajax({
    //     method:"POST",
    //     url:"http://42.192.83.143:8089/AjaxMockServer/info",
    //     contentType:"application/x-www-form-urlencoded",
    //     body:"username=abc&password=123",
    //     callback:function(status,response){//调用的时候传入了两个参数,对应的参数
    //         console.log("响应状态码:" + status + ",响应正文:" + response)
    //     }
    // })
</script>
</html>

附:关于ajax产生原因

JS是单线程运行(也就是代码一行一行运行)。所以:

ajax异步:发送ajax请求后(send调用),后边的JS代码还可以继续执行。在ajax事件发生以后,由系统内核来通知执行ajax的回调函数。

ajax产生原因:(1)不刷新页面就可以发送http请求:用户体验更好
(2)相同一个页面,动态通过响应数据来生成局部的页面内容,如果是服务端直接返回变化后的html,也不好,因为数据量比较大所以效率比较低。如果是ajax就效率很高。

七丶HTTPS

<1>什么是HTTPS

HTTPS就是在HTTP协议的基础上引入了一个加密层,也就是套上了一层
TLS/SSL协议。
HTTP协议都是按文本的方式明文传输,所以过程不太安全,可能被篡改。毕竟从源主机(客户端发送请求的主机)到目的主机(服务端进程所在的主机)会经过很多的网络设备。

经过的网络节点(网络硬件设施):路由器,集线器,光猫,主机

如果说想要搞破坏,那么从这些设备都可以下手,也就是都可以篡改http原始数据(请求,响应都可能)
篡改方法过程:
<1>如果说url网址是a,那么改成b
<2>通过referer知道上一个页面,然后就加一些小广告什么的。

<2>相关概念

1.明文:可以直接看到的原始数据
2.密文:加密后,看不到原始数据的文本
3.加密:将明文通过加密手段,转换为密文
4.解密:把密文通过解密手段,转换为明文
5.密匙:可以基于一个密匙(一般是字符串),将一个数据(文本或者二进制数据
)进行加密,使用相同的密匙就可以解密。

对称加密

对称加密:加密和解密使用同一个密钥,效率高

非对称加密

加密和解密使用两个不同的秘钥(但是两个密匙之间有一定的联系),效率比较低

公钥和私钥的关系,作用,位置

关系:通过私钥可以用一定的算法来生成一个公钥
作用:都可以加密,也都可以解密
位置:可以是客户端,也可以是服务端

HTTPS单双向认证

HTTPS单向认证:

客户端希望访问的网站是没有被篡改过的网站(保证服务端的安全),服务端保存自
己的私钥,服务端提供公钥(通过自己私钥生成)给客户端(保证服务端安全)。
这种适应于开放性的网站,不必须要在服务端保证客户端的安全(所有人都可以
访问)。

HTTPS双向认证:

需要保证服务端是安全的(客户端拿到的服务端数据是安全的),也要保证客户端
的安全(服务端也希望客户端是安全的,经常用于限制一些只能某类用户访问的网
站)

<3>生成密钥的流程(非对称加密)

在这里插入图片描述

1.客户端给出协议版本号,一个客户端生成的随机数,以及客户端支持的加密方法(明文传输)
2.服务端确认双方使用的加密方法,并给出数字证书(包含公钥和网站信息),以及一个服务器生成的随机数(Server random)。(明文传输)
3.客户端确认数字证书有效,然后生成一个新的随机数(Premaster secret),并且使用数字证书中的公钥,加密这个随机数,发给服务端。(密文传输)。
4.服务端使用自己的私钥,获取客户端发来的随机数
5.客户端和服务端根据约定的加密方法,使用前面的三个随机数,生成“对话秘钥”,用来加密接下来的整个过程。

<4>总结

看着很复杂,其实就是

(1)非对称加密生成对话秘钥:两次明文传输两个随机字符串,一次密文传输一个
随机字符串,客户端和服务端都分别基于这三个随机字符串来生成相同的对话密钥
2.对称加密来传输数据:客户端第一步生成秘钥对发送的请求数据加密,服务端也
使用同样的密钥对接收的请求进行解密,响应也是类似,服务端使用对话密钥加密
,客户端使用同样的密钥解密。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值