目录
错误说法:GET请求的长度是存在上限的,主要是因为URL的长度存在上限
错误说法2:POST的传输的数据量比GET更多,原因是URL有上限
错误说法3:GET只能传输文本数据,POST可以传输文本和二进制数据
⑨浏览器禁止网页中的JS代码访问磁盘,而不是浏览器本身不能访问磁盘。
一、协议
网络上的信息传输,本质上都是一些光信号或者电信号。从网络通信的软件层面上来讲,最重要的概念,就是协议。实际生活中,存在很多服务器和主机,协议可以让传递信息的双方可以对的上号。
在当前计算机的网络通信领域中,涉及到的协议有很多,目前先重点学习HTTP协议。当我们使用浏览器打开网页的时候,100%涉及到了HTTP协议,使用一些app如美团等,大部分80%以上涉及到了HTTP协议。
二、HTTP协议
2.1 定义
HTTP协议,全称为超文本传输协议,是一种应用非常广泛的应用层协议。
2.2 HTTP的工作过程
客户端:主动发起网络请求的一端
服务器:被动接收网络请求的一端
请求:客户端发给服务器的数据
响应:服务器返回给客户端的数据
HTTP的重要特点:一发一收这样的模式
当我们在浏览器输入一个网址,此时浏览器就会给服务器发送一个HTTP请求,当服务器收到这个请求后,经过计算处理,就会返回一个HTTP响应。
在实际中,我们在访问一个网站时,可能涉及到的不止一次的HTTP请求、HTTP响应的交互过程。我们可以借助抓包工具fiddle来更清晰的观察整个过程。
网络编程中常见的模式:
一发一收:web开发中,最常见的方式。
多发一收:上传大文件
一发多收:看直播
多发多收:串流(steam link、moonlight)
不同的应用程序,有不同的通信特点。应用程序要采用哪种模式,主要取决于程序员的代码是如何编写的。
DDOs攻击
黑客动用大量的计算资源,即黑客手里掌握很多机器,每个机器上都要客户端,黑客操作这些机器同时给某个网站发送请求,由于每个服务器可以处理的数据都是存在上限的,如果请求过多,就会导致服务器过载。
DDOS攻击的解决方案
只要服务器能够识别出攻击请求的特征,对于此类攻击请求直接拒绝服务就行。
三、抓包工具fiddle的使用
3.1 使用前的注意事项
为了使得fiddle可以抓到使用HTTPS协议的请求,我们需要先勾选一个协议:
打开fiddle—Tools—Options
3.2 下载
下载地址:Fiddler | Web Debugging Proxy and Troubleshooting Solutions
3.3 了解fiddle的界面
左侧窗口:显示了所有的HTTP请求/响应,可以选中某个请求查看详情。fiddle会记录机器上每个程序和服务器之间的http请求,不仅仅只记录浏览器的。
右侧上方:显示了HTTP请求的报文内容. (切换到Inspectors-Raw标签可以看到详细的数据格式)
右侧下方:显示了HTTP响应的报文内容. (切换到Raw标签可以看到详细的数据格式)
请求和响应的详细数据,可以通过右下角的View in Notepad通过记事本打开。
可以使用ctrl + a全选左侧的抓包结果, delete键清除所有被选中的结果。
3.4 了解fiddler的工作原理
fiddler相当于一个代理。当客户端浏览某个网址时,就会把HTTP请求先发给Fiddler, Fiddler再把请求转发给服务器。当服务器返回数据时,fiddler先拿到数据,再把数据交给浏览器。
因此,Fiddler对于浏览器和服务器之间交互的数据细节,都是非常清楚的。
访问一个网站,会触发很多HTTP请求,需要在多个请求中找自己关注的。
Q:抓包wifi或者路由器的信息和抓包网站信息一样吗?
路由器就像一座强,访问的网站数据都是通过桥来传递的,在桥上面就能看到通过的数据。fiddle就像桥下面有一道门。数据先通过门再来到桥上。
一个桥上可能会有很多门。站在桥上看到的是汇总信息,站在门口,只能看到这个门过来的信息。
四、HTTP协议的格式
4.1 HTTP请求格式
4.2 HTTP响应格式
响应的正文,往往都是被显示在浏览器上的,最常见的响应正文格式就是HTML。但是很多网站返回的HTML是被压缩过的,可以点击:
来解压缩。
压缩之后,网络传输的数据量就变少了,就更节省网络带宽了。
针对服务器来说,常见的硬件资源分为:CPU、内存资源、硬盘资源、带宽资源,目前在国内,带宽资源是最贵的。
4.3 协议格式总结
Q:为什么HTTP报文中要存在空行?
因为HTTP协议并没有规定报头中的键值对个数。空行就当是报头的结束标志,是报头和请求正文之间的分隔符。
HTTP协议在传输层依赖TCP协议,TCP是面向字节流的,如果没有这个空行,就会出现粘包问题。
五、HTTP请求(Request)
5.1 URL(统一资源定位符)
互联网上的每个文件都有一个唯一的URL,他包含的信息指出文件的位置以及浏览器该如何处理它。
一个完整的URL:
http://user:pass@www.example.jp:80/dir/index.html?uid=1#ch1
http:协议方案名。常见的是http和https
user:pass:登录信息。现在的网站进行身份认证一般不通过URL进行了,一般都会省略。
www.example.jp:服务器地址,可以是一个IP地址(网络上的一个具体的位置),也可以是一个域名。通过DNS系统会将域名解析为IP地址。
80:端口号。端口号用来区分一个主机上的不同程序。一个IP地址可以定位到具体的主机,一个主机上有很多程序在跑,将这个请求交给哪个程序,就会使用端口号来区分。每个程序在访问网络的时候,会关联上一个或者多个端口号,通过端口号就能区分当前的请求给哪个程序。当端口号省略的时候,浏览器会自动根据协议类型自动决定使用哪个端口。http协议默认使用的是80端口,https默认使用443端口。
dir/index.html:带层次的文件路径。表示访问服务器上的哪个资源,比如,访问的是哪个html哪个图片
uid=1:查询字符串,queryString,本质是一个键值对结构,键值对之间使用&分割,键和值之间使用=分割。如果queryString里面包含了特殊符号或者中文符号,就需要进行URLencode。主要是因为URL本身就有一些表示特定含义的符号,如果queryString中也存在特殊符号,就可能导致URL格式错误,因此,需要对这些特殊符号进行转义。
有的浏览器,即使程序员在代码中没有进行RULencode,也会自动encode,有的浏览器,就不会自动rulencode,会出现错误。
ch1:片段标识图。主要用于页面的跳转。
5.2 认识方法
5.2.1 所有方法
方法 | 说明 | 方法 | 说明 |
GET | 获取资源 | OPTIONS | 询问支持的方法 |
POST | 传输实体主体 | TRACE | 追踪路径 |
PUT | 传输文件 | CONNECT | 要求用隧道协议连接代理 |
HEAD | 获取报文首部 | LINK | 建立和资源之间的联系 |
DELETE | 删除文件 | UNLINE | 断开连接关系 |
本来,设计HTTP的作者希望通过不同的方法来表示不同的语义。但是,现在程序员使用这些方法,都是非常随心所欲的,具体这个方法起到了啥作用,完全看程序员代码里面是咋写的。
虽然HTTP中有很多方法,但是最常用的就只有两个,GET和PUT。
同时最主流的HTTP协议版本是1.1。版本2和版本3(最新的)目前还没普及。
5.2.2 GET方法
GET是最常用的HTTP方法,常用于获取服务器上的某个资源。
很多时候都会触发这个GET方法的请求,如:
①在浏览器窗口输入一个URL后回车,此时服务器就会构造一个HTTP GET请求。
②HTML中的img的src 属性写了一个URL
③HTML中的 a标签和script标签的href属性写了一个URL。
④JS中的Ajax也可以构造HTTP GET请求。
⑤ 各种编程语言只要能够访问网络,就都可以构造出HTTP GET请求。
在浏览器输入baidu.com后,通过fiddler我们可以看到:此时就发送了一个HTTP GET请求:
从上面抓包结果我们可以看到HTTP GET请求的特点:
①首行的第一个部分是GET
②URL里面的query string可以为空,也可以不为空。
③GET请求中有很多组header这样的键值对。
④GET请求一般body是空的。(GET请求其实也可以有body,但是很少见,绝大部分情况下是没有body的)
错误说法:GET请求的长度是存在上限的,主要是因为URL的长度存在上限
在RFC2616(RFC标准系列文档):里面约定了很多和网络协议相关的标准。里面指出:对URL的长度没有规定。
5.2.3 POST方法
HTML中的form标签构造POST请求
JS中的ajax也可以构造POST请求。
最常见的场景,就是登录。用户输入账号和密码之后,就会产生POST请求。登录b站,以其中一个抓包结果为例:
①首行的第一个部分是POST
②URL后面没有query string,一般都是没有的,个别情况下可能会有。
③GET请求中有很多组header这样的键值对。
④body一般不为空。body里面具体的数据格式,由请求中的header中的Content-Type来描述,body的具体长度,由header中的Content-Length来描述。
5.2.4 GET和POST的区别
(1)GET和POST没有本质上的区别,使用GET的场景,完全可以使用POST代替;使用POST的场景,也完全可以使用GET代替。
(2)但是在使用上,有一些细节上的区别:
①语义不同,习惯上,GET用于从服务器获取数据,POST是客户端给服务器发送数据。
②习惯上,GET的body一般为空,把客户端的数据通过queryString来传输。POST的queryString一般为空,把客户端的数据通过body来传输。
③GET请求一般是幂等的,POST请求一般是不幂等的。(幂等:如果请求被重复发送了,不会产生负面效果)
④GET请求可以被缓存,保存在浏览器的收藏夹内。POST不可以。
错误说法1:POST比GET更安全
他们认为:GET把参数放在queryString,就会在浏览器的URL看到当前的参数不安全。POST将参数放在body里,信息不会显示在浏览器地址栏里,更安全。
安全不安全,取决于是否加密以及加密算法的强度,和东西在URL还是body里面没关系,一抓包都能看见
错误说法2:POST的传输的数据量比GET更多,原因是URL有上限
在标准中已经说明,不对URL的长度进行限制
错误说法3:GET只能传输文本数据,POST可以传输文本和二进制数据
GET完全可以传输二进制数据,只要对二进制数据进行URLencode,就可以放到URL里了。实在不行,GET也可以将数据放在body里。
5.3 认识报头(header)中常见的属性
5.3.1 Host
表示服务器主机的地址和端口。
Host这个属性,在URL不也有吗?
主要是因为网上存在一种特殊的程序,叫做代理。
5.3.2 Content-Length
表示body中的数据长度,单位是字节。
5.3.3 Content-Type
表示body的格式。常见取值有:
①application/x-www-form-urlencoded:form 表单提交的数据格式(类似于query String)。body格式形式如:
username=123&password=456
②multipart/form-data: form 表单提交的数据格式(在 form 标签中加上enctyped="multipart/form-data" . 通常用于提交图片/文件。
③application/json:数据为 json 格式。现在非常流行的一种取值。JS里的对象就是这种格式,JSON格式,就是源自于JS对象的格式)。body格式形式如:
{"username":"123456789","password":"xxxx"}
5.3.4 User-Agent(UA)
表示浏览器/操作系统的属性。
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
其中:Windows NT 10.0; Win64; x64 表示操作系统信息。Chrome/100.0.4896.127 Safari/537.36:表示当前的浏览器是啥以及浏览器的版本是啥。
以前的作用:最早的网站,就只是一个"报纸",此时的浏览器,也就只能显示文字和图片。后来,网页更丰富了,可以支持视频/音频了。不是所有的浏览器都能放视频,再后来,网页更丰富了,支持JS进行交互了,不是所有的浏览器都支持。再后来,网页逐渐的功能越来越多,浏览器的版本也在逐渐更新。都可以让网站的实现者,根据版本信息来做兼容性设计。网站的开发者,就可以根据HTTP请求中的UA来进行判定。UA里带有浏览器的具体型号,网站的开发者就可以看看当前用户的浏览器是否能播放视频。如果能播放,就返回带视频的页面.如果不能播放,就返回不带视频的页面。"兼容性"
虽然使用UA可以实现刚才说的,返回两个不同版本的页面,来兼容手机和PC,但是实际开发中,很少这样做。这样做成本比较高,要同时维护两套页面。现在更主流的做法,是采取"响应式布局" ,在页面CSS中通过“媒体查询"功能(CSS3的特性),根据屏幕的尺寸,自动设置不同的样式来兼容不同的设备。
5.3.5 Refer
表示这个页面是从哪个页面跳转过来的。
如果直接在浏览器中输入URL,或者直接通过收藏夹访问页面时是没有Refer的。
5.3.6 Cookie
打开百度的首页,
点Cookie就能看到里面的具体内容。
里面的Cookie信息是按照域名进行组织存储的。
Cookie里面是一些键值对,Cookie里的键值对表示的含义,都是程序员自定义的。想在Cookie里面放啥,都可以。
Cookie机制存在的目的,就是为了能在浏览器这一端,保存一些程序员自定义的数据。
在此有一个小疑问:程序员不能直接将需要保存的数据存在客户端浏览器所在的主机的硬盘上吗?
答案:不可以。如果浏览器可以直接访问本地文件,很多时候不小心打开某个网页,网页往硬盘上写一个病毒程序,就可能把电脑的文件全删了。因此,浏览器为了保证安全性,禁止网页中的代码访问主机的硬盘,即无法通过JS读写文件。这就会让前端失去持久化存储的能力,但是这种能力在某些时候又不能缺失。
解决方案:虽然浏览器不让程序员直接去操作客户端的文件,但是提供了一个cookie这样的机制,按照键值对进行存储,来代替直接访问文件。Cookie的内容是浏览器管理的,本质上也是保存在硬盘上,会持久化存储。
①Cookie是什么?
Cookie是浏览器提供的能让程序员在客户端存储数据的能力。
②Cookie存的是啥?
Cookie里存的是键值对格式的数据,键值对之间,使用;分割。键和值之间,使用=分割。
③Cookie从哪来?程序员如何往Cookie里存东西?
浏览器里面存储的Cookie都是从响应报头里的set-cookie字段中来,每个set-cookie字段里面都包含一个cookie的键值对,浏览器拿到这个响应之后,就会把这个set-cookie里的内容保存到本地。
set-cookie是程序员在服务器代码中填写构造。
④Cookie去哪?谁来使用Cookie?
Cookie字段会在后续的请求中,把浏览器本地存储的这些键值对,再发回给服务器。即服务器这段的代码使用Cookie。
⑤了解过程
⑥Cookie的一个典型应用—保存客户端的登录状态
⑦ Cookie是唯一的浏览器本地存储的机制吗?
不是,还有其他的:
LocalStorage:这个是从HTML5开始,浏览器提供的一种新的本地存储的机制,只用这个完全可以代替Cookie。
indexDB:浏览器提供了一组类似于SQL这样的接口,可以在浏览器本地以类似于数据库的方式存储数据。
⑧Cookie的缺陷
每次请求,都需要把该域名下所有的Cookie通过HTTP请求返回服务器,这就注定Cookie的存储容量是有限的。
⑨浏览器禁止网页中的JS代码访问磁盘,而不是浏览器本身不能访问磁盘。
六、HTTP响应详解
6.1 状态码
状态码标识访问一个页面的结果。
常见的状态码:
状态码 | 含义 |
200 OK | 访问成功 |
404 Not Found | 没有找到资源 |
403 Forbidden | 访问被拒绝(没有访问权限的表现) |
405 Method Not Allowed | 当前的HTTP方法,服务器不支持 |
500 Internal Server Error | 原因只有一个,服务器代码出现了崩溃、异常 |
504 Gateway Timeout | 一般是服务器负载太高,导致服务器等待的太久了 |
302 Move temporarily | 呼叫转移 |
301 Moved Permanently | 永久重定向 |
类别 | 原因 | |
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
6.2 响应报头
响应报头的基本格式和请求报头的格式基本一致。类似于Content-Type、Content-Length等属性的含义也和请求中的含义一样。
七、通过form表单构造HTTP请求
7.1 form标签发送GET请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="https://www.baidu.com/" method="get">
<input type="text" name="name" >
<input type="text" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
form的action属性:HTTP请求的URL
form的method属性:HTTP请求的方法
form的name属性:queryString的key
input输入的内容:queryString的value
构造post请求时,直接将代码中的method改为post就可以。
从抓包结果可以看出: queryString移动到了body中。
八、通过ajax构造HTTP请求
8.1 ajax
ajax 全称 Asynchronous Javascript And XML,是 2005 年提出的一种 JavaScript 给服务器发送
HTTP 请求的方式。是当前进行前后端交互最主要的一个方式。
XML:是一种文件的组织方式。这种组织方式非常类似于HTML,也采用标签化的组织方式。以前,用XML来组织格式化的数据;现在,有了JSON、YML这种更新更好用的格式,以及逐渐替代了传统的XML。
Asynchronous:异步的(并联):例如:浏览器通过img来获取图片、通过link来获得css、通过script获得css
Synchronous同步的(串联):例如,浏览器解析一个页面,是同步的按照从上到下来解析的
8.2 JQuery
使用JS原生的Ajax方式来请求服务器,这种写法非常麻烦。第三方库JQuery里面对ajax提供了一个更简便的封装版本。因此,采用该库来写ajax的代码。
安装使用:在JS中使用第三方库很简单,只要在代码中引入对应库的CDN链接即可。即使用script标签,把JQuery的CDN地址写进去就行。
CDN:
是互联网的一种基础设施,即一组由运营商提供的服务器,存在的目的就是为了加快用户的访问速度。
假设:客户端在西安,百度的服务器在北京,虽然网线、光纤中的数据传输速度很快,但是空间上的距离也会产生影响。在传输的过程中,涉及到很多路由器、交换机之间的转发,尤其是传输一些比较大的文件时,这样的影响会更明显。百度就和运营商谈,将他的logo等一些文件存放在西安比较闲的服务器上,如果用户访问,就优先访问运营商在西安的服务器。
运营商在全国各地都有cdn服务器,各种互联网产品都可以付费使用运营商的cdn服务器,来存放各自的一些静态资源,用户在访问的时候,就会自动的就近访问。
8.2 发送GET请求
<body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$.ajax({
url: 'http://baidu.com',
method: 'GET',
success: function(data, status) {
console.log(data);
console.log(status);
}
});
</script>
</body>
$:是一个变量名,是jQuery中定义好的一个对象。jQuery里面的各种方法,都是这个对象的成员。
url:访问的服务器的URL;
method:方法;
success:function:回调函数。当请求发送成功后收到响应了,就会由浏览器来自动的调用这个函数;
data:响应的body;
status:响应的状态。
8.3 发送POST请求
<body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$.ajax({
url: 'http://42.192.83.143:8089/AjaxMockServer/info',
method: 'POST',
contentType:'text/plain',
data:'this is body',
success: function(data, status) {
console.log(data);
console.log(status);
}
});
</script>
</body>
写data的时候一定要加上contentType
8.4 是否可以基于ajax来写爬虫
结论:是不行的。
Ajax里面有一个重要的限制,就是默认情况下不能跨域,ajax是通过js代码触发的,js代码又是在html里面,访问这个html就有一个域名,称为域名1。ajax里面构造的请求也有一个域名,称为域名2。ajax默认情况下,要求域名1和域名2必须是一样的,如果不一样就会访问出错。
其实,大部分服务器都不允许跨域访问,因此使用Ajax一般只能访问自己的服务器,无法访问别人的服务器。之所以有跨域的限制,也是为了保证安全性。