看懂《书源规则:从入门到入土》(1)HTTP基础
前言:
我不喜欢伸手党。觉得不懂可以问很正常没问题,但应该是自身尽力后依然无法解决后再问。而且应该给予解答者尊重,而不是一味的骚扰甚至恶语相向。
相信不少曾经有想写书源的想法酷友应该有和我一样的经历,阅读的书源规则文档每个字都能看懂
,但组合在一起就不知道是什么东西了
,于是放弃了
。
下面一系列图文我会尽力让大家能看懂书源文档,编写一些简单的书源。希望能减轻大佬们应付小白的压力。
该系列图文我会尽量面向小白写得浅显易懂,让没什么基础的酷友能轻松上手。
(尽管我真的很想直接甩MDN(Mozilla Developer Network)文档上来你们自己去悟
)
书源规则文档链接:
查看链接
免责声明:
该系列(看懂《书源规则:从入门到入土》)图文仅供学习使用,自行编写的规则所造成的后果请自行承担,本人概不负责。
消歧义:
本章所说的http协议包括常规的http协议及https协议中的http部分
本章可能需要涉及的工具:
1:浏览器(推荐最新的chrome或firefox。当然你非要用internet explorer 6是你的自由)
2:抓包工具(比如fiddler。如果涉及https包需要进行mitm(Man-In-The-Middle attack,中间人攻击),请自行部署mitm证书)
3:对于部分人可能还要翻译工具
-------------
首先,什么是http?
http(HyperText Transfer Protocol,超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。
说简单点,就是客户端(通常是浏览器)与网站服务器进行交互的协议,详细介绍去看Wikipedia,我这不讲历史。
---------------
http请求(request):
http请求是我们向服务器发送到指令,希望服务器提供怎样的服务。一个http请求报文通常分为方法(method)、请求头(headers)、请求体(body)三个部分。
http请求报文示例,图源MDN
方法:
在HTTP/1.1协议中一共定义了8种方法来以不同方式操作指定的资源,分别是:GET , HEAD , POST , PUT , DELETE , TRACE , OPTIONS , CONNECT。
在本文中,只需要知道GET和POST就可以了
,其他有兴趣的可以去看Wikipedia或MDN。
GET:请求一个指定资源的表示形式。
POST:用于将实体提交到指定的资源。
在上述示例中,我们看到了第一行"GET / HTTP/1.1",这就是这一个http请求所用的“方法”。
🦊:您好我是浏览器,服务器大哥,我想通过 http 1.1(HTTP/1.1) 协议 获取(GET) 站点 根目录(/) 的资源。
请求头:
好了,现在服务器知道了客户端希望获得怎样的服务了。但method里是不是写得太简陋了,你不打算提点要求吗?
这就是请求头的作用,向服务器发送一些附加信息,希望服务器提供怎样的“个性化”服务。
示例中,我们用了两个字段:
Host:developer.mozilla.org
Accept-Language:fr
这是什么意思呢?别急,咋们慢慢来。
🦊:我希望看到的是 developer.mozilla.org 这台 主机(host) 上的网站,我能 接受的语言(accept language) 是 法语(fr是french的缩写)。
请求体:
示例里没有,后面有我会再讲。这部分是客户端提交给服务器处理的数据。
综上,示例中的请求报文的意思就是:
🦊:您好我是浏览器,服务器大哥,我想通过http 1.1协议获取站点根目录的资源。我希望看到的是developer.mozilla.org这台主机上的网站,我能接受的语言是法语。我暂时没有其他数据要您处理了(请求体:无),麻烦大哥
。
------------
http响应(response):
(非重点,一笔带过)
http响应是服务器处理客户端的请求后,向客户端发送的处理结果。一个http响应报文通常包含状态(status)、响应头(headers)、响应体(body)三个部分。
http响应报文示例,图源MDN
状态:
表示服务器对这个请求处理的结果。示例中的意思是:http 1.1请求已处理,状态码200(处理成功)。
响应头:
服务器发送的附加信息,表示服务器的一些工作状态和下面会提到的响应体的一些情况。
示例中的响应头
Date:Sat
, 09 Oct 2010 14:28:02 GMT
Server:Apache
Last-Modified:Tue, 01 Dec 2009 20:18:22 GMT
ETag:"51142bc1-7449-479b075b2891b"
Accept-Ranges:bytes
Content-Length:29769
Content-Type:text/html
的意思是:
当前 时间(date) 格林尼治标准时间2010年10月9日14时28分2秒星期六 服务端程序(server) Apache 你请求的资源 最后变动时间(Last-Modified) 格林尼治标准时间2009年12月1日20时18分22秒星期二 标记(etag) 51142bc1-7449-479b075b2891b 可接受的 范围请求单位(accept-ranges) 是 字节(bytes) 内容(响应体)长度(Content-Length) 29769字节 内容类型(Content-Type) html文本(text/html)
响应体:
服务器根据请求返回的数据。
综上:示例中的响应报文的意思是:
🥔:浏览器弟弟,你的http1.1请求已经处理成功。现在服务器时间是格林尼治标准时间2010年10月9日14时28分2秒星期六,服务端程序是Apache,你请求的资源最后变动时间是格林尼治标准时间2009年12月1日20时18分22秒星期二,资源标记51142bc1-7449-479b075b2891b,服务器可接受的范围请求单位是字节,一会发生给你的内容长度29769字节,类型是html文本,内容(响应体)是<!DOCTYPE html...
------------
看到这里,也许有同志会来问了。上面水了那么多字,怎么还没入题
?
怎么会没入题呢?写源的时候不用写搜索吗?搜索不就是我们告诉服务器,我们希望得到怎样的书吗。
那怎么告诉服务器?用http请求啊
。现在我们以一个网站为例,看看这个请求是什么玩意。
按照流程,我们是不是应该先输入名字,然后点击搜索
。那么在个过程里面,究竟发生了什么?
现在,我们打开浏览器控制台看看
现在看到了,搜索功能是写在一个form(表单)元素里的,当点击提交时这个表单收集到的数据会通过http post方法提交到/search.html
现在我们抓取一下点击搜索时浏览器和服务器之间的http报文。(因为在我是在手机码字,用fiddler不那么方便,此处用小黄鸟做演示
。原理都是一样的)
请求
一大堆字段看不懂对不?没关系,大部分都不用理解,咱们只挑需要的讲。
方法:POST /search.html h2
通过http2(h2)协议向网站的/search.html这个资源发送一个post请求。
请求头:
accept-language:zh,zh-SG;q=0.9,en-US;q=0.8,en;q=0.7
可接受的语言:中文,中文-新加坡,英语-美国,英语
accept-encoding:gzip,deflate
可接受的压缩算法:gzip , deflate
请求体:s=%E5%AE......(下面那堆字,懒得打
)
向服务器发送“s=完美世界&submit=”这个字符串。
至于为什么是一堆%XX这样的代码是因为这部分内容不是ASCII编码,所以浏览器需要进行转换,于是就变成了这样的uri编码了。
一个字都看不懂的自觉向上滚
,去复习一下。
响应
同上,咱们只挑重要的讲
状态:h2 200
这个http2请求已处理,状态码200(处理成功)
响应头:
content-type:text/html;charset=UTF-8
内容类型:html文本,字符集UTF-8
content-encoding:gzip
内容压缩算法
:gzip
响应体:
下面那堆乱码
因为已经被压缩了,所以这里看起来是乱码。浏览器收到响应后会把响应体用gzip算法解压就能得到一个正常的html文档了
-------------
编写搜索:
好了,我们已经知道了搜索时请求的资源是/search.html,
请求方式是post,
请求体的写法是s=书名&submit=
请求头一般是可选的,但有时候需要指定某些字段(比如指定某个user-agent(用户代理,俗称ua),使服务器发送电脑端网页)
那么我们应该怎么写一个请求给网站,来获取搜索结果呢?
这个网站可能稍复杂点,不能一条url搞定,所以我们用json(JavaScript Object Notation)方式编写。
json通过 键:值 对的方式指定属性和属性值,键值对之间用英文逗号分隔(换行并非必须,只是为了“美观”),括号里最后一个键值对末尾不要加逗号,就像这样:
{
a:1,
b:'text',
c:{
d:true
},
e:[1,2,3]
}
根据文档,搜索>搜索地址 部分我们应该这样写
/search.html,{
'headers':{},
'body':'s={{key}}&submit=',
'method':'POST'
}
注:
1
:{{key}}是一个阅读的内部变量,表示搜索的书名,发送请求时程序会自动替换。
2:如果不指定请求头的话最好把headers部分删掉。
-------------
结语&预告:
本章扯了那么多,终于解决了发送搜索的问题。那么拿到服务器响应后我们该如何过滤和呈现呢?
敬请期待下一章:html基础
-------------
引用:
超文本传输协议 - 维基百科:
查看链接
HTTP - MDN:
查看链接