小蔡学Java

HTTP

2023-08-28 13:12 782 0 JavaWeb JavaWeb

前言

    HTTP是应用层最典型协议,为什么这么说?看看他的应用场景:

绝大部分的浏览器与服务器的交互;
绝大部分手机APP与服务器交互;
服务器之间相互调用也可以使用HTTP;

即使最新的HTTP版本已经3.0了,但本文重点介绍1.1版本;

对HTTP协议总体的一个认识:

一、HTTP协议是什么?

    HTTP是前后端交互的桥梁,是最典型的“一问一答”的模型协议,HTTP协议主要用于用于Web浏览器和Web服务器之间的通信,想要学习一个协议,主要就是学习HTTP的报文格式;

    例如:当你在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成最后看到的网页。

构造一个HTTP请求本质上就是往TCP socket中,按照以下将要讲的格式来写入数据即可;

1.1、HTTP请求格式(以百度网页为例)务必要掌握~

1.2、HTTP响应格式

对HTTP协议具体的一个认识:

一、什么是URL

    URL就是我们实际输入的网址,也叫“唯一资源定位符”,他就像门牌号一样,通过他就可以在服务器中找到我们需要访问的资源;

1.1、URL格式

 协议方案名:常见的有http和https,https实际上就是http加密后的协议;
登录信息:现在的网页进行身份认证不通过URL了,所以可以省略;
服务器地址:就是服务器的IP地址,也可以写成域名;(域名和IP地址是等价的,域名是方便用户认识产生的一种形式,通过DNS域名解析系统,就可以将域名转化成IP地址发送给服务器)
服务器端口号:标识了要访问的目标服务器是哪个进程;
带层次的文件路径:服务器上的文件路径(这个路径就描述了展示网页所需要的资源的位置在哪),HTTP服务器一般不会把电脑上所有资源都提供到网页上,通常是指定某个目录为根目录,这个目录里的内容,才是用户可以访问的;如果这些内容是服务上真实的文件资源,那么就叫做——访问静态资源;若是HTTP服务器没有访问真实数据,而是在内存中构造出的HTML,返回到浏览器,这叫做——访问动态资源;
查询字符串:前面是一个问号,后面跟一个键值对结构(完全是程序员自定义的)键值之间通过&分割,称为query string,浏览器给服务器传递的必要参数;

可以将URL形象成这样一个东西~(如下)

 http://门头沟学院3号餐厅:65号窗口/麻辣烫?口味=香辣&是否加香菜=多放点&是否放蒙汗药=多放点&几套餐具=3

1.2 encode / decode

把原始字符转义后的字符就是 URL encode(编码);

把转义后的字符还原成原始的字符就是 URL decode(编码);

例如一段搜狗的网址

这里用%分割开的实际上就是个十六进制数字,将他通过ascii码表进行翻译,就可以知道他要表示的内容了~

二、HTTP协议中两个重要方法

2.1、GET

GET是HTTP请求最常用的方法,本质上就是浏览器通过GET方法,向服务器发起GET请求,从服务器拿到相应的数据;

什么时候会触发这个请求?

1.浏览器的地址栏中输入URL,就会触发GET;

2.HTML里的link、a、img、script会触发GET请求;

3.html中的form标签可以构造出GET请求;

4.使用 JavaScript 的 ajax 也可以构造 POST 请求

很多人的误区:“GET请求长度长度最多是1KB / 2KB ...?”;这个说法真的正确吗?
  • HTTP 协议由 RFC 2616 标准定义, 标准原文中明确说明: "Hypertext Transfer Protocol -- HTTP/1.1," does not specify any requirement for URL length.

  • 也就是说,标准中,并未对URL的长度做出限制;其实虽然没有提到有长度上限,但是浏览器和HTTP服务器在实现的时候,可能有长度上线,也可能没有,具体要看如何实现了;

2.2、POST

POST是用来将用户输入的数据发送给服务器的一种方法;(例如一些网站的登录界面,当你输入账号和密码,提交以后,便会执行这个方法);

什么时候会触发这个请求?
  • 1.通过 HTML 中的 form 标签可以构造 POST 请求

  • 2.使用 JavaScript 的 ajax 也可以构造 POST 请求

POST请求的特点:

  • 1.POST请求中,首行第一部分为POST;

  • 2.URL一般没有query string;

  • 3.header 部分有若干个键值对结构.

  • 4.body部分的数据格式有很多种,一般不会为空;

2.3、常考面试题——谈谈GET和POST的区别?

第一步、直接盖棺定论:

    GET和POST没有本质区别,使用GET的场景基本都可以使用POST代替,使用POST的场景也可以用GET代替;

第二步、谈细节上的区别:

细节一:(语义上)

GET语义:从服务器获取一个数据;

POST语义:往服务器提交一个数据;

虽然HTTP协议说是这么说,但是很多程序员还是没有遵守这个约定~

细节二:(使用习惯上)

习惯上,给服务器传递数据,GET通常放在URL的query string中,POST通常是放在body;中;

GET能放在body中吗?可以滴,HTTP客户端支持,但是浏览器不一定支持;

 POST能放在query string中吗?可以呢!浏览器和客户端都支持~

细节三:(幂等)

GET请求建议实现成“幂等”的,POST不做要求;(幂等性:比方说一个函数的方法是1 + 1,结果等于2,你调用一次结果是2,你调用n次结果依然是2,不会改变);

服务器设计时会提供一些api:api传入的参数视为输入,返回的结果视为输出;基于GET的api建议设置成幂等的,POST不做要求;

细节四:(缓存)

在幂等的基础上,GET请求结果是可以被缓存的,POST一般不缓存;

 这时浏览器默认的,若当前GET时幂等的,就不做处理,让浏览器缓存;若当前GET不是幂等的,就需要通过特殊技避免产生缓存;(技巧就是让GET请求的URL都不同,通过特殊的query string保证URL不同);

POST比GET更安全,这个说法正确吗?

虽然在登录界面GET把参数放到的URL中确实不好,但是放到POST的body中,也一样没有更安全;因为咱们平时谈到的是否安全,是指:你的数据被黑客截获后,会不会对你造成信息泄漏这样的影响,只要你的代码没有进行加密,就谈不上安全;

HTTP协议中的请求头(header)

一、Host

    表示服务器主机的地址和端口(要去哪才能找到服务器), 这里端口号可以省略,若省略,则使用默认值;(HTTP的默认值是80,HTTPS的默认值是443)

问题一:URL里的IP和端口号和Host有区别吗?

    有区别,URL的IP和端口和Host有可能一样,也有可能不一样,当请求是经过代理来访问的时候,可能会不一样(以上截图是博主通过Fiddler抓包截下来的,然而以上结论在Fidder没有体现出来);

为什么?如下图情况:

二、Content-Length / Content-Type

这两个字段不一定有,但若有一个,就会有另一个;具体看是否存在body;

2.1、Content-Length 表示body中的数据长度;

Content-Length有什么用呢?

HTTP协议,在传输层是基于TCP(HTTP3.0之前是这样,3.0就是UDP了),而TCP是面向字节流的,那么就会存在粘包问题~ 如何解决呢?1.约定一个分隔符;2.约定报文长度;这时Content-Length确定了body数据的长度,就可以很好的解决粘包问题~

2.2、Content-Type 表示请求的body中的数据格式;

Content-Type有什么用呢?

body中的数据可以是很懂中格式,不同的格式对于接收方来说,解析方式是截然不同的;可能会有的格式例如:form表单构造的请求、query string的键值对格式、以及json格式...

三、User-Agent(简称:“UA”)

简而言之:UA主要包含的就是“操作系统信息”和“浏览器信息”,描述了用户在使用什么样的设备上网;

User-Agent 有什么用呢?

在互联网不发达的时候:通过UA手机浏览器/操作系统信息,就知道该支持什么页面了;若是一个原始的浏览器,就返回一个纯文本页面,若是一个先进的浏览器,就返回一个功能丰富的页面(这样做是为了考虑兼容性);//这些都是2015年左右的问题,现在以及不是问题了,那UA就没用了吗?当然不会,往下看~

在互联网发达的时候(当今社会):可以根据UA识别出PC、平板、手机,分别开发不同版本的页面;(UA确实削弱了,但至少还可以用在服务器统计用户的设备情况~);

四、Referer

表示当前页面是从哪个网页跳转过来的,若在浏览器地址栏直接输入一个地址,或是直接点击收藏夹,就没有referer;

如下图:(从百度搜索minecraft,Fiddler捕捉到的Referer就是百度的网址)

 什么?你问我有什么用?

哈哈,在浏览器里贴小广告,统计是哪个浏览器被用户的点击了,并记录点击次数;这有什么用?赚钱啊哈哈哈,开发浏览器的公司自己统计一次,广告商自己统计一次,最后对比看没问题,就会像浏览器结算广告费~ 什么小广告?就是下图这样的小广告~

五、Cookie

有时候需要让网页存储一些简单数据,但由于网页禁止js访问电脑硬盘(原因:安全性),所以就提供了特殊的api给网页用,Cookie就是最经典的一个方案,是浏览器在本地存储数据(存储到硬盘上)的一种机制;

Cookie如何组织信息的?键值对的形式!(如下图)

Cookie是用来存放什么数据的?

上次访问网页的时间;
当前网页的访问次数
当前访问网页网页的身份标识(最典型的应用场景);

特点:

Cookie是按照域名维度来组织的,不同域名下有不同的Cookie;
和query string一样,是程序员自定义的;
每一个Cookie都是一个键值对;
Cookie有个过期时间,到时自动清除;

注意:Cookie不是缓存,是持久化数据的手段(保存在硬盘上),缓存的数据是用来提高访问速度的;

5.1、Cookie从哪里来?

Cookie存在于浏览器,来源于服务器;

解释:在网页中我们所观察的Cookie都是浏览器访问了某一个服务器后,服务器返回一个响应报文,在响应header中包含 一个/多个 Set-Cookie这样的资源(程序员自己在服务器代码中写的),浏览器接收响应后,就见Set-Cookie这样的数据保存到浏览器本地;

如下图Fiddler所捕捉到的Set-Cookie:

5.2、Cookie到哪里去?

来自服务器,存储到浏览器,最后返回到服务器;

解释:当浏览器保存了cookie后,下次访问同一网站,就会把之前存在本地的Cookie作为身份标识在http请求的header给返回到服务器,服务器就知道,喔,又是你来了~就把上次加载好的数据作为响应返回给浏览器;

5.3、Cookie 典型应用场景——维持登录状态

在某网站上成功登录后,浏览器会记住当前登录用户的身份信息,接下来再访问该网站的其他页面时,服务器也能知道是谁在登录;

具体解释:

HTTP响应中的状态码

一、状态码(重点)

状态码是一个数字,描述了当前请求的“状态”(成功、失败、失败的原因);

以下介绍几个常考的

1.1、200 OK

这是一个最常见的状态码, 表示访问成功.

1.2、404 Not found

这是一个常见的错误,问题的原因是因为请求路径写错了;

解释:请求中的url就是路径,表示你要访问的服务器上的资源,如果这个资源服务器上没有,就会返回404;

1.3、403 Forbidden

403就表示访问被拒绝,也就是没有权限访问; 事实上:状态码中以4开头的,都是客户端这边处了问题;

1.4、405 Method Not Allowed

我们知道的 HTTP 中所支持的方法, 有 GET, POST, PUT, DELETE 等.

但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法)

1.5、500 Internal Server Error

500表示服务器内部错误,服务器代码执行过程中,出现了异常;

1.6、504 Gateway Timeout

表示访问超时,一般在服务器请求量很大的时候,服务器符合比较重,就容易出现;

规律总结:服务器处理问题,一般就是5来开头;

1.7、302临时重定向

访问一个旧的URL,自动准一道新的URL上;

常见场景:

服务器地址迁移;
搜索引擎点击跳转;

1.8、301 Moved Permanently

永久重定向. 当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址. 301 也是通过 Location 字段来表示要重定向到的新地址.

1.9、状态码表参照

如何构造一个HTTP请求?

一、通过前端构造的三种方法:

1.1、通过浏览器自己构造

工具:浏览器;

打开你的浏览器,在地址栏里写url,按下回车,就可以构造出get请求;(如下图)

1.2、通过form表单构造

工具:vscode;

步骤一:在vscode中,创建html文件,构造一个form表单;(具体的如下代码)

<body>
    <form action="https://cn.bing.com/" method="get">
        <input type="text" name="a">
        <input type="text" name="b">
        <input type="submit" value="提交">
    </form>
</body>

解释:

form表单的关键作用是传递键值对
action是你选择的网页;
method是构造http请求的方法,这里只支持 get 和 post ;
input标签用来构造键值对数据,一个input的就是一个键值对,name表示“键”,用户输入的数据表示“值”,最后通过submit来提交,发送请求
若使用get方法,上述键值对就会存到url的query string中;若使用post方法,上述键值对就会放到body中(格式与query string一样);

步骤二:打开HTML网页,输入你想输入的值;(如下图)

最后:网页跳转,地址栏(如下图)

1.3、通过ajax构造

工具:vscode,jquery第三方库;

    最初ajax主要是借助HTTP传输xml,现在xml用的少了,因此ajax往往用来传输其他数据,例如json;

    form表单构造的数据一定会出发页面跳转,时间慢,开销大,所以并不是一件好事,使用ajax就可以不触发跳转,达到“局部刷新”的效果;

    步骤一:ajax api是浏览器自带的,原生api不太好用,所以可以使用第三方库,代替原生api;打开jquery官网(js中最知名的第三方库之一),复制script链接;

     步骤二:输入以下代码;
    <script src="https://lib.baomitu.com/jquery/1.12.4/jquery.min.js"></script>
    <script>
        $.ajax({
            type: 'get',
            url:'https://cn.bing.com/',
            success: function(body) {
                //服务器返回正确响应(状态码:200),浏览器就会调用这个函数,处理响应;
                //参数body就是响应的正文
                console.log("OK~");//打印日志
            },
            error: function() {
                //服务器返回一个错误响应,浏览器就会调用error对应的函数
                console.log("error~");//打印日志
            }
        })
    </script>

解释:

  • 第一个script标签的src属性里的url就是刚刚从第三方库中所获取的;
  • type表示使用get方法;
  • url表示选择的网页;
  • success表示当服务器返回正确响应(状态码:200),浏览器就会调用他对应的函数,处理响应;参数body就是响应的正文;
  • error表示服务器返回一个错误响应,浏览器就会调用error对应的函数;

最后:打开html,打开调试,会观察到如下信息:

解释原因:

这里出错了;原因是跨域(一个页面在域名a下通过ajax访问域名b的资源),这里浏览器是禁止的,除非跨域的网站返回的响应中告诉浏览器可以;(大部分网站是不可以的);

解决方法:

这里我们可以自己写一个服务器,把页面放到自己的服务器上,让页面访问自己服务器的资源;(这里不展开讲,后期会出博客);

二、通过postman构造

工具:

    属于是一个专门构造HTTP请求的第三方工具,主要是帮助接口测试的,简而言之:它可以用来更方便的构造HTTP请求;

具体步骤如下图:

最后结果:

三、通过Postman生成各种语言HTTP请求

具体步骤如下图: (简直不要太爽~)

评论( 0 )

  • 博主 Mr Cai
  • 坐标 河南 信阳
  • 标签 Java、SpringBoot、消息中间件、Web、Code爱好者

文章目录