HTTP协议
HTTP协议是什么
HTTP协议(全称叫做"超文本传输协议") 是一种应用非常广泛的应用层协议
HTTP协议处于TCP/IP协议栈的应用层 HTTP协议在传输层是基于TCP的(HTTP/1 ,HTTP/2是基于TCP,最新版本HTTP/3是基于UDP的,当今互联网使用最多的是HTTP/1.1)
HTTP协议格式
HTTP 是一个文本格式的协议. 可以通过 Chrome 开发者工具或者 Fiddler 抓包, 分析 HTTP 请求/响应的细节.
抓包工具的使用
以 Fiddler 为例. (下载地址: https://www.telerik.com/fiddler/)
安装过程比较简单, 一路 next 即可.
- 左侧窗口显示了所有的 HTTP请求/响应, 可以选中某个请求查看详情.
- 右侧上方显示了 HTTP 请求的报文内容. (切换到 Raw 标签页可以看到详细的数据格式)
- 右侧下方显示了 HTTP 响应的报文内容. (切换到 Raw 标签页可以看到详细的数据格式)
- 请求和响应的详细数据, 可以通过右下角的 View in Notepad 通过记事本打开.
可以使用 ctrl + a 全选左侧的抓包结果, delete 键清除所有被选中的结果.
抓包工具的原理
Fiddler 相当于一个 “代理”.
浏览器访问 sogou.com 时, 就会把 HTTP 请求先发给 Fiddler, Fiddler 再把请求转发给 sogou 的服务器.
当 sogou 服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器.
因此 Fiddler 对于浏览器和 sogou 服务器之间交互的数据细节, 都是非常清楚的.
代理就可以简单理解为一个跑腿小弟. 你想买罐冰阔落, 又不想自己下楼去超市, 那么就可以把钱给你的跑腿小弟, 跑腿小弟来到超市把钱给超市老板, 再把冰阔落拿回来交到你手上. 这个过程中, 这个跑腿小弟对于 “你” 和 “超市老板” 之间的交易细节, 是非常清楚的.
注意:因为现在互联网很多网站使用的HTTPS协议,HTTPS协议和HTTP协议大体是一样的,所以用Fiddler也可以抓到.Fiddler刚安装的时候,默认是没有启用HTTPS,如果抓到HTTPS的包,就会出现错误
此时就需要手动开启HTTPS
抓包结果
以下是一个 HTTP请求/响应 的抓包结果.
HTTP请求
-
首行:[方法]+[URL]+[版本] -
Header:请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束 -
空行 -
Body:空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有 一个Content-Length属性来标识Body的长度;
HTTP响应
- 首行: [版本号] + [状态码] + [状态码解释]
- Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
- Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中.
协议格式总结
通过抓包,我们看到了HTTP协议的请求和相应,那么接下来就来认识一下HTTP协议吧
请求分为4部分(可以看上面获取的请求)
-
首行:包含了三部分
- HTTP的方法:方法大概描述了这个请求想要干嘛
- URL:描述了要访问的网络上的资源具体是在哪里
- 版本号:HTTP/1.1表示当前使用的HTTP的版本是1.1
-
请求行(Header) :包含了很多行 ? 每一行都是一个键值对 键和值之间使用 : 空格进行分割 -
空行:相当于请求头的结束标志(类似于链表的null) -
正文请求 :可选的,不一定有
相应同样分为4部分
-
首行:包含3部分
- 版本号:和请求的版本号一样
- 状态码:描述了这个响应是一个成功的还是失败的,以及不同的状态码,描述的失败的原因
- 状态码描述:通过一个/一组简单的单词,来描述当前的状态码的状态
-
响应头(Header) ? 也是键值对形式,每个键值对占一行每个键和值之间使用: 空格来分割 -
空行:表示响应头的结束标记 -
响应正文(body)服务器给客户端返回的具体数据
HTTP请求
认识URL
URL的基本格式
平时我们俗称的 “网址” 其实就是说的 URL (Uniform Resource Locator 统一资源定位符).
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它.
-
协议方案名:描述了当前的URL是给哪个协议使用的 ? HTTP://给HTTP协议使用 ? HTTPS:// 给HTTPS协议使用 ? jdbc:mysql:// 给jdbc:mysql使用 -
登录信息:上古时期使用的,现在基本很多用到 -
服务器地址:当前要访问的主机是啥 可以是一个ip地址,也可以是一个域名 -
端口号:表示当前要访问的主机上的哪个应用程序(大部分是省略的,省略不代表没有,而是浏览器会赋予默认值,对于http开头的url,会用80当做默认端口;对于https开头的url,默认会使用443当做默认端口 -
带层次的文件路径:,描述了当前要访问的服务器的资源是啥 -
查询字符串:本质上就是浏览器/客户端,给服务器传递的自定义的信息,相当于对获取到的资源提出进一步的要求,查询字符串和路径之间用?来分割 -
片段标识符:描述了要访问的当前html页面中具体的子部分,能够控制浏览器滚动到对应位置
URL小结:
对于url来说,里面的结构看起来比较复杂,其实最重要的,和开发最紧密相关的,主要只有4部分
- ip地址/域名
- 端口号(经常是小透明)
- 带层次结构的路径
- query string 查询字符串
URL encode
当url出现一些特殊的字符的时候,就需要对特殊字符进行转义,这个转义的过程就叫做encode,反之,把转义后的内容还回来就叫做decode
像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
此时搜索C++,此时的query string 显示的就是 C%2B%2B
? url encode的规则,就是把要转义的内容的ASCII码值取出来,用十六进制表示同时加上%
在实际开发过程中,尤其是前后端进行交互的时候,特别是需要通过URL给服务器传递一些信息的时候,一定要针对里面的特殊符号进行url encode
认识方法
HTTP中使用最多的就是GET和POST方法
GET方法
GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源.
在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求
GET 请求的特点
- 首行的第一部分为 GET
- URL 的 query string 可以为空, 也可以不为空.
- header 部分有若干个键值对结构.
- body 部分为空.
POST方法
POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器(例如登陆页面).
通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求.
POST 请求的特点
- 首行的第一部分为 POST
- URL 的 query string 一般为空 (也可以不为空)
- header 部分有若干个键值对结构.
- body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由
- header 中的 Content-Length 指定.
经典面试题:谈谈 GET 和 POST 的区别
- 语义不同: GET 一般用于获取数据, POST 一般用于提交数据.
- GET 的 body 一般为空, 需要传递的数据通过 query string 传递, POST 的 query string 一般为空, 需要传递的数据通过 body 传递
- GET 请求一般是幂等的, POST 请求一般是不幂等的. (如果多次请求得到的结果一样, 就视为请求是幂等的).
- GET 可以被缓存, POST 不能被缓存. (这一点也是承接幂等性).
补充说明:
- 关于语义: GET 完全可以用于提交数据, POST 也完全可以用于获取数据.
- 关于幂等性: 标准建议 GET 实现为幂等的. 实际开发中 GET 也不必完全遵守这个规则(主流网站都有 “猜你喜欢” 功能, 会根据用户的历史行为实时更新现有的结果.
- 关于安全性: 有些资料上说 “POST 比 GET 请安全”. 这样的说法是不科学的. 是否安全取决于前端在传输密码等敏感信息时是否进行加密, 和 GET POST 无关.
- 关于传输数据量: 有的资料上说 “GET 传输的数据量小, POST 传输数据量大”. 这个也是不科学的, 标准没有规定 GET 的 URL 的长度, 也没有规定 POST 的 body 的长度. 传输数据量多少, 完全取决于不同浏览器和不同服务器之间的实现区别.
- 关于传输数据类型: 有的资料上说 “GET 只能传输文本数据, POST 可以传输二进制数据”. 这个也是不科学的. GET 的 query string 虽然无法直接传输二进制数据, 但是可以针对二进制数据进行 url encode.
其他方法
- PUT 与 POST 相似,只是具有幂等特性,一般用于更新
- DELETE 删除服务器指定资源
- OPTIONS 返回服务器所支持的请求方法
- HEAD 类似于GET,只不过响应体不返回,只返回响应头
- TRACE 回显服务器端收到的请求,测试的时候会用到这个
- CONNECT 预留,暂无使用
这些方法的 HTTP 请求可以使用 ajax 来构造. (也可以通过一些第三方工具)
任何一个能进行网络编程的语言都可以构造 HTTP 请求. 本质上就是通过 TCP socket 写入一个符合 HTTP 协议规则的字符串.
认识请求"报头" (header)
header 的整体的格式也是 “键值对” 结构.
每个键值对占一行. 键和值之间使用分号分割
报头的种类有很多, 此处仅介绍几个常见的.
Host
表示服务器主机的地址和端口.
Content-Length
表示 body 中的数据长度.
HTTP是基于TCP的协议
TCP是一个面向字节流的协议,其中就有一个粘包问题,此时就挺合理的运用应用层协议.明确包和包之间的边界
- 使用分割符:请求中有空行,就分割了body
- 使用长度:Content-Length就明确了body的长度
Content-Type
表示请求的 body 中的数据格式
常见选项:
- application/x-www-form-urlencoded: form 表单提交的数据格式. 此时 body 的格式形如:
title=test&content=hello
multipart/form-data: form 表单提交的数据格式(在 form 标签中加上enctyped="multipart/form-data" . 通常用于提交图片/文件. body 格式形如:
Content-Type:multipart/form-data; boundary=----
WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
- application/json: 数据为 json 格式. body 格式形如
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16
a861fa2bddfdcd15"}
关于 Content-Type 的详细情况: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
User-Agent (简称UA)
表示浏览器/操作系统的属性. 形如
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36
其中 Windows NT 10.0; Win64; x64 表示操作系统信息
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 表示浏览器信息.
Referer
表示这个页面是从哪个页面跳转过来的. 形如上图中:
Referer:https://gitee.com/login
如果是通过浏览器地址栏直接输入地址或者直接点击收藏夹,这时候就没有Referer
Cookie
Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据).
Cookie就是浏览器给页面提供的一个能够持久化存储数据的机制
Cookie的具体组织形式
- 先按照域名来组织,针对每一个域名,分配一个小房间,例如:访问百度,就会给百度增域名记录一组cookie,访问码云,就会给码云分配一组cookie
- 每个小房间又会按照哦键值对的方式组织数据
cookie的数据都是服务器返回给客户端的,包含了这样的header,就是服务器完成身份验证之后,就给客户端返回一些具体的信息,信息就是通过set-Cookie这样的相应报头来表示的
登录过程
登录之后访问其他页面
存储在服务器上的信息,叫做session会话
服务器管理了很多的session,每个session都存储了用户的关键信息,每个session也有一个sessionId(会话的标志)
理解登录过程
这个过程和去医院看病很相似.
-
到了医院先挂号. 挂号时候需要提供身份证, 同时得到了一张 “就诊卡”, 这个就诊卡就相当于患者的 “令牌”. -
后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别出当前患者的身份. -
看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁了. (类似于网站的注销操作) -
又来看病, 可以办一张新的就诊卡, 此时就得到了一个新的 “令牌”
认识请求 “正文” (body)
正文中的内容格式和 header 中的 Content-Type 密切相关. 上面也罗列了三种常见的情况.
- application/x-www-form-urlencoded
POST https://gitee.com/profile/upload_portrait_with_base64 HTTP/1.1
Host: gitee.com
Connection: keep-alive
Content-Length: 107389
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
Accept: */*
X-CSRF-Token: 6ROfZGr4Y7Qx8td1TuKCnrG8gbODLCSUqUBZSw2b+ac=
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/91.0.4472.101 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: https://gitee.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://gitee.com/HGtz2222
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: oschina_new_user=false; user_locale=zh-CN; yp_riddler_id=1ce4a551-a160-
4358-aa73-472762c79dc0; visit-gitee--2021-05-06%2010%3A12%3A24%20%2B0800=1;
sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22726826%22%2C%22first_id%22%3
A%22175869ba5888b6-0ea2311dc53295-303464-2073600-
175869ba5899ac%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E
7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%
9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%2
4latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%22175869ba5888b6-
0ea2311dc53295-303464-2073600-175869ba5899ac%22%7D; remote_way=svn;
tz=Asia%2FShanghai;
Hm_lvt_24f17767262929947cc3631f99bfd274=1622637014,1622712683,1622863899,1623298
442; gitee_user=true; Hm_lpvt_24f17767262929947cc3631f99bfd274=1623298560;
gitee-sessionn=c0hXQ0I5SjR1bWg5M01IR3RYS3hLT0RhelN1aFVuMExKdEdSSmRaQWIwRy9QWFUwV0thdzV1alIzYj
RaOU9ZeDdkZEJZK2RtTVRNeTNFRHNYVW9ha2hEcWJyclIwS1NVRG1EL0xxTmJXSGxvSzh3c28zOHBia1
pIOFQrU3RYeWE0bE13S09DTm5MZWZ5WW5WUVFpSzFiMGFWbHRDQ0xRakc1Um5yY21HQllqeUpNLzBvZF
gxbHVhN09uK2h1VVVmRHZkS3BmVGEwcDhyNjJVb1p0RFRLY0VOem5vNEEvd0FuYzJJYlhZcGlyenZQc3
dSbXBNUWI3UUwrRDBrV2N0UHZRdjFBUXF5b0Y0L1Vrd09pQVBKNkdjZmY5cHlDTCtMWG4ya0tIaW5LcE
tBTkw4cGFGVjhUQ0djMWhkOXI0bUFteUY4VW80RHl2T2Q2YmxwR1d3M3Rad1RhZWhhdnNiTTNrcE1RV2
NyZ1dYeDRoR0dpanh4bERNMTBuenB1NkgxLS16QUdJS3NlZG9mTVBtYlVlREppck1BPT0%3D-
-898d1284181ca494918d29ac44f9a3a79d448a9b
avatar=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAPgAAAD4CAYAAADB0Ss
LAAAg......
- multipart/form-data
POST https://v.bitedu.vip/tms/oss/upload/file HTTP/1.1
Host: v.bitedu.vip
Connection: keep-alive
Content-Length: 293252
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
Authorization: Bearer
eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjFiYThjMDM5LWUyN2UtNDdhZS04YTAzLTN
mNWMzY2UwN2YyNSJ9.VQWoqrrgWZpDNc81tYfSvna8A9uZP6QKqucnvGMuY8wbavHF30rx7NG9VxnAo1
78V0nOJBd75QxRvNRgpY6-Iw
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/91.0.4472.101 Safari/537.36
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundary8d5Rp4eJgrUSS3wT
Accept: */*
Origin: https://v.bitedu.vip
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://v.bitedu.vip/personInf/student?userId=665
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: rememberMe=true; username=18691491410; AdminToken=eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjFiYThjMDM5LWUyN2UtNDdhZS04Y
TAzLTNmNWMzY2UwN2YyNSJ9.VQWoqrrgWZpDNc81tYfSvna8A9uZP6QKqucnvGMuY8wbavHF30rx7NG9
VxnAo178V0nOJBd75QxRvNRgpY6-Iw
------WebKitFormBoundary8d5Rp4eJgrUSS3wT
Content-Disposition: form-data; name="file"; filename="李星亚 Java开发工程师.pdf"
Content-Type: application/pdf
%PDF-1.7
%3 ?
1 0 obj
<</Names <</Dests 4 0 R>> /Outlines 5 0 R /Pages 2 0 R /Type /Catalog>>
endobj
3 0 obj
<</Author ( N v~N?) /Comments () /Company () /CreationDate
(D:20201122145133+06'51') /Creator ( ? W P S e [W) /Keywords () /ModDate
(D:20201122145133+06'51') /Producer () /SourceModified (D:20201122145133+06'51')
/Subject () /Title () /Trapped /False>>
endobj
13 0 obj
<</AIS false /BM /Normal /CA 1 /Type /ExtGState /ca 1>>
endobj
- application/json
POST https://v.bitedu.vip/tms/login HTTP/1.1
Host: v.bitedu.vip
Connection: keep-alive
Content-Length: 105
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/91.0.4472.101 Safari/537.36
Access-Control-Allow-Methods: PUT,POST,GET,DELETE,OPTIONS
Content-Type: application/json;charset=UTF-8
Access-Control-Allow-Origin: *
Accept: application/json, text/plain, */*
Access-Control-Allow-Headers: Content-Type, Content-Length, Authorization,
Accept, X-Requested-With , yourHeaderFeild
Origin: https://v.bitedu.vip
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://v.bitedu.vip/login
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: rememberMe=true; username=123456789
{"username":"123456789","password":"xxxx","code":"u58u","uuid":"9bd8e09ea27b48cd
acc6a6bc41d9f462"}
HTTP 响应详解
认识"状态码" (status code)
状态码表示访问一个页面的结果. (是访问成功, 还是失败, 还是其他的一些情况…)
以下为常见的状态码.
200 OK
这是一个最常见的状态码, 表示访问成功.
404 Not Found
没有找到资源. 要访问的资源不存在
403 Forbidden
虽然资源存在,但是没有访问权限
405 Method Not Allowed
前面我们已经学习了 HTTP 中所支持的方法, 有 GET, POST, PUT, DELETE 等.
但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法).
500 Internal Server Error
服务器出现内部错误. 一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会产生这个状态码.
504 Gateway Timeout
当服务器负载比较大的时候, 服务器处理单条请求的时候消耗的时间就会很长, 就可能会导致出现超时的情况.
302 Move temporarily
临时重定向.
理解 “重定向”
就相当于手机号码中的 “呼叫转移” 功能.
比如我本来的手机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋友知道新号码,
只要我去办理一个呼叫转移业务, 其他人拨打 186-1234-5678 , 就会自动转移到 135-1234-5678 上.
在登陆页面中经常会见到 302. 用于实现登陆成功后自动跳转到主页.
响应报文的 header 部分会包含一个 Location 字段, 表示要跳转到哪个页面.
例如: 码云的登陆页面 https://gitee.com/login
抓包看到的响应结果:
HTTP/1.1 302 Found
Date: Thu, 10 Jun 2021 06:49:26 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Keep-Alive: timeout=60
Server: nginx
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
Expires: Sun, 1 Jan 2000 01:00:00 GMT
Pragma: must-revalidate, no-cache, private
Location: https://gitee.com/HGtz2222
Cache-Control: no-cache
Set-Cookie: oschina_new_user=false; path=/; expires=Mon, 10 Jun 2041
06:49:24 -0000
Set-Cookie: gitee_user=true; path=/
Set-Cookie: gitee-sessionn=UG5CdVZQUkVUamxsWis3b0JoL2dyTDRLVTk1WXVCK2VwaGd0OGFKdjBjdjB4K0RiWTh2ZmhrZ
GM1cU0vOFN2VGdNcVY5dU5rSzZHeVFBcVZ3OTBaSmZmZzRYQUdsa2tHMnFIeU9SQlN4Z2pleDNM
Y3ExZUF6QWpHTHlVeTZOWFVHSVBxbTVuZGJpandHekdaRVBTUVd0ejZUNHNvTllSODBiNHd6NWN
CRUZ0UzZCZW1mRTBZUUdmOE5JTWVKdnJMMzdQcHFBMk5nUmNjMWpmc3daTElYU2hhbkEwQm41NH
NlZ2RwM3QxSjZMTndSNjcyNDd6YUVoS0ZmUWpLTDQ2KzlzZVowZTFLaUNPTmVDajVOb2k0MWFRc
GkzWVQ2QUxuWXJLeTRqL2JHaUE9LS0xYlVDOWVkc0JiM2xucVk0am1LRHFnPT0%3D-
-58854ce81d6c67bb7b9a0fdd6fe18a8ebdb3d753; domain=.gitee.com; path=/;
HttpOnly
X-Request-Id: d45ade01dbeffc99a3688d3411b3381f
X-Runtime: 0.133587
Content-Length: 92
<html><body>You are being <a
href="https://gitee.com/HGtz2222">redirected</a>.</body></html>
301 Moved Permanently
永久重定向. 当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址.
301 也是通过 Location 字段来表示要重定向到的新地址.
状态码小结:
认识响应 “报头” (header)
响应报头的基本格式和请求报头的格式基本一致.
类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义一致.
Content-Type
响应中的 Content-Type 常见取值有以下几种:
text/html : body 数据格式是 HTMLtext/css : body 数据格式是 CSSapplication/javascript : body 数据格式是 JavaScriptapplication/json : body 数据格式是 JSON
认识响应 “正文” (body)
正文的具体格式取决于 Content-Type.
通过 form 表单构造 HTTP 请求
form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET 或者 POST 请求.
不要把 form 拼写成 from!!
form 发送 GET 请求
form 的重要参数:
- action: 构造的 HTTP 请求的 URL 是什么.
- method: 构造的 HTTP 请求的 方法 是 GET 还是 POST (form 只支持 GET 和 POST).
input 的重要参数:
- type: 表示输入框的类型. text 表示文本, password 表示密码, submit 表示提交按钮.
- name: 表示构造出的 HTTP 请求的 query string 的 key. query string 的 value 就是输入框的用户输入的内容.
- value: input 标签的值. 对于 type 为 submit 类型来说, value 就对应了按钮上显示的文本.
<form action="myPath" method="get">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
此时的HTTP请求
- form 的 action 属性对应 HTTP 请求的 URL
- form 的 method 属性对应 HTTP 请求的方法
- input 的 name 属性对应 query string 的 key
- input 的 内容 对应 query string 的 value
form发送POST请求
<form action="myPath" method="post">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
构造的 HTTP 请求
主要的区别:
- method 从 GET 变成了 POST
- 数据从 query string 移动到了 body 中.
通过ajax 构造 HTTP请求
从前端角度, 除了浏览器地址栏能构造 GET 请求, form 表单能构造 GET 和 POST 之外, 还可以通过 ajax 的方式来构造 HTTP 请求. 并且功能更强大.
ajax 全称 Asynchronous Javascript And XML, 是 2005 年提出的一种 JavaScript 给服务器发送HTTP 请求的方式.
特点是可以不需要 刷新页面/页面跳转 就能进行数据传输
在 JavaScript 中可以通过 ajax 的方式构造 HTTP 请求
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$.ajax({
type: 'get',
url: 'myPath',
success: function(body) {
console.log(body);
}
});
</script>
HTTP请求
|