文章目录

  • 一、请求行属性
    • 1.1 URL
    • 1.2 方法(method)
      • 1.2.1 GET 方法
      • 1.2.2 POST 方法
      • 1.2.3 其他方法
      • 1.2.4 GET 和 POST 的区别
  • 二、常见请求"报头" (header)
    • 2.1 其他报头
    • 2.2 Cookie(重要)
  • 三、请求 "正文" (body)

一、请求行属性

1.1 URL

1.1.1 URL 基本格式

平时我们俗称的 “网址” 其实就是说的 URL (Uniform Resource Locator 统一资源定位符).互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它.URL 的详细规则由 因特网标准RFC1738 进行了约定

一个具体的 URL:

https://v.bitedu.vip/personInf/student ? userId=10000&classId=100

  1. https : 协议方案名. 常见的有 http 和 https, 也有其他的类型. (例如访问 mysql 时用的
    jdbc:mysql )
  2. user:pass : 登陆信息. 现在的网站进行身份认证一般不再通过 URL 进行了. 一般都会省略
  3. v.bitedu.vip : 服务器地址. 此处是一个 “域名”, 域名会通过 DNS 系统解析成一个具体的 IP 地址.(通过 ping 命令可以看到, v.bitedu.vip 的真实 IP 地址为 118.24.113.28 )
  4. 端口号: 上面的 URL 中端口号被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
  5. /personInf/student : 带层次的文件路径.描述了当前要访问的服务器资源文件(/ 也要包括)
  6. userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使用 & 分隔. 键和值之间使用 = 分隔. 是客户端给服务器传递的自定义信息,对获取到的服务器资源文件提出了进一步要求
  7. 片段标识: 此 URL 中省略了片段标识. 片段标识主要用于页面内跳转

上述属性比较抽象,举个例子理解下:

好比我去驿站取一张床.服务器地址就告诉我该去哪个驿站,端口号就是对应的哪个工作人员,带层次的文件路径就是取件码,查询字符串就可以是我告诉工作人员这个床太大了,我要分四次来取走等进一步要求

注意:

  1. 虽然URL中写的是一个文件路径,但是不一定服务器上就真实存在一个对应的文件.这个文件可能是磁盘上一个真实的文件,也可能是虚拟的,由服务器代码构造出的一个动态数据
  2. 带层次的文件路径和查询字符串是用 分割
  3. 查询字符串完全是由程序猿自己定义的,外人不认识,可以通过这样的方式来自定制传输我们需要的信息给服务器
  4. 使用 ping 命令查看域名对应的 IP 地址

1.在开始菜单中输入 cmd , 打开 命令提示符
2.在 cmd 中输入 ping v.bitedu.vip , 即可看到域名解析的结果
PS: 有的电脑上 ping 命令会报错 ping 不是内部或外部命令,也不是可运行的程序或批处理文件 . 这
种情况是因为有的 Windows10 默认没有启用 ping 命令


1.1.2 关于 URL encode

像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.(中文字符同样也需要转义)

转义的规则如下: 将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式,例如(“+” 被转义成了 “%2B”):

urldecode就是urlencode的逆过程


1.2 方法(method)

认识 “方法” (method):

在HTTP请求中,涉及到的最主要两种方法就是GET 和 POST

1.2.1 GET 方法

GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源.在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求

后面我们还会学习, 使用 JavaScript 中的 ajax 和 form表单来构造 GET 请求

使用 Fiddler 观察 GET 请求

选中第一条观察部分:

可以看出第一条是通过浏览器地址栏发送的 GET 请求

下面的和 sogou 域名相关的请求, 有些是通过 html 中的 link/script/img 标签产生的, 例如

有些是通过 ajax 的方式产生的, 例如

GET 请求的特点:

  1. 首行的第一部分为 GET
  2. URL 的 query string 可以为空, 也可以不为空.
  3. header 部分有若干个键值对结构.
  4. body 部分为空

扩展:

关于 GET 请求的 URL 长度问题
网上有些资料上描述: get请求长度最多1024kb 这样的说法是错误的.
HTTP 协议由 RFC 2616 标准定义, 标准原文中明确说明: “Hypertext Transfer Protocol –
HTTP/1.1,” does not specify any requirement for URL length.
没有对 URL 的长度有任何的限制.
实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最大长
度是不同的, 但是现代浏览器支持的长度一般都很长; 在服务器端, 一般这个长度是可以配置的.


1.2.2 POST 方法

POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器(例如登陆页面).
通过 HTML 中的 form 标签, 或者使用 JavaScript 的 ajax 可以构造 POST 请求

使用 Fiddler 观察 POST 方法:
在比特教务系统的登陆页面, 输入用户名, 密码, 验证码之后, 点击登陆, 就可以看到 POST 请求.

点击这个请求, 查看请求详情

POST 请求的特点:

  1. 首行的第一部分为 POST
  2. URL 的 query string 一般为空 (也可以不为空)
  3. header 部分有若干个键值对结构.
  4. body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由header 中的 Content-Length 指定.

1.2.3 其他方法

  1. PUT 与 POST 相似,只是具有幂等特性,一般用于更新
  2. DELETE 删除服务器指定资源
  3. OPTIONS 返回服务器所支持的请求方法
  4. HEAD 类似于GET,只不过响应体不返回,只返回响应头
  5. TRACE 回显服务器端收到的请求,测试的时候会用到这个
  6. CONNECT 预留,暂无使用

这些方法的 HTTP 请求可以使用 ajax 来构造. (也可以通过一些第三方工具)

任何一个能进行网络编程的语言都可以构造 HTTP 请求. 本质上就是通过 TCP socket 写入一个符
合 HTTP 协议规则的字符串

1.2.4 GET 和 POST 的区别

注意: GET 和 POST 没有本质区别,细节上有差异.它们的使用场景都是可以相互替换的

  1. 语义不同: GET 一般用于获取数据, POST 一般用于提交数据.反之当然也可以
  2. GET 的 body 一般为空, 需要传递的数据通过 query string 传递, POST 的 query string 一般
    为空, 需要传递的数据通过 body 传递
  3. GET 请求一般是幂等的, POST 请求一般是不幂等的. (如果多次请求得到的结果一样, 就视为
    请求是幂等的).
  4. GET 可以被缓存, POST 不能被缓存. (这一点也是承接幂等性).

补充说明:

关于语义: GET 完全可以用于提交数据, POST 也完全可以用于获取数据.
关于幂等性: 标准建议 GET 实现为幂等的. 实际开发中 GET 也不必完全遵守这个规则(主流网站都有 “猜你喜欢” 功能, 会根据用户的历史行为实时更新现有的结果.
关于安全性: 有些资料上说 “POST 比 GET 请安全”. 这样的说法是不科学的. 是否安全取决于前端在传输密码等敏感信息时是否进行加密, 和 GET POST 无关.
关于传输数据量: 有的资料上说 “GET 传输的数据量小, POST 传输数据量大”. 这个也是不科学的, 标准没有规定 GET 的 URL 的长度, 也没有规定 POST 的 body 的长度. 传输数据量多少,完全取决于不同浏览器和不同服务器之间的实现区别.
关于传输数据类型: 有的资料上说 “GET 只能传输文本数据, POST 可以传输二进制数据”. 这个也是不科学的. GET 的 query string 虽然无法直接传输二进制数据, 但是可以针对二进制数据进行 url encode.


请求行中还涉及到版本问题,在初识篇已经介绍,这里就不过多赘述

二、常见请求"报头" (header)

header 的整体的格式也是 “键值对” 结构.每个键值对占一行. 键和值之间使用分号分割.报头的种类很多,当前介绍几种常用的,如下

2.1 其他报头

Host: 表示服务器主机的地址和端口.域名可以通过DNS转换成IP地址

Content-Length: 表示 body 中的数据长度. 可以明确包和包之间的界限,粘包问题

Content-Type: 表示请求的 body 中的数据格式.具体格式如下文


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: 表示这个页面是从哪个页面跳转过来的. 形如

https://v.bitedu.vip/login

注意: 如果直接在浏览器中输入URL, 或者直接通过收藏夹访问页面时是没有 Referer 的.


2.2 Cookie(重要)

浏览器给页面提供的一种能够持久化储存数据的机制方便后续访问完网站.Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回一些数据和 SessionID,往往可以通过这个SessionID 实现 “身份标识” 的功能).

Cookie的组织形式: 先按照域名来组织,针对每个域名分别分配一个Cookie,如我访问百度,浏览器会给百度域名分配一个cookie.在每个Cookie中又会按照键值对的当时来组织数据,如下:

PS:每个不同的域名下都可以有不同的 Cookie, 不同网站之间的 Cookie 并不冲突.

通过抓包观察页面登陆的过程(以码云为例):

  1. 为了方便观察, 先清除掉之前登陆的 cookie(如上述图片即可找到清除)
  2. 登陆操作:准备好登录页面,将fiddler中的抓包清除后点击登录,观察抓包情况

登录请求:

登录响应:

可以看到, 响应中包含了 3 个 Set-Cookie 属性.其中我们重点关注第三个. 里面包含了一个 gitee-session-n 属性(即SessionID), 属性值是一串很长的加密之后的信息. 这个信息就是用户当前登陆的身份标识. 也称为 “令牌(token)

  1. 访问其他码云页面
    登陆成功之后, 此时可以看到后续访问码云的其他页面(比如个人主页), 请求中就都会带着刚才获取到的Cookie 信息

请求中的 Cookie 字段也包含了一个 gitee-session-n 属性, 里面的值和刚才服务器返回的值相同. 后续只要访问 gitee 这个网站, 就会一直带着这个令牌, 直到令牌过期/下次重新登陆

理解上述过程:

这个过程和去医院看病很相似.

  1. 到了医院先挂号. 挂号时候需要提供身份证, 同时得到了一张 “就诊卡”, 这个就诊卡就相当于
    患者的 “令牌”.
  2. 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别
    出当前患者的身份.
  3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁
    了. (类似于网站的注销操作)
  4. 又来看病, 可以办一张新的就诊卡, 此时就得到了一个新的 “令牌”

关于Session会话:

在服务器这边就需要记录令牌信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.

上述讲到的Cookie可以存储数据,但是保存的数据量有限,所以这些数据真正的保存在服务器的Session中,每个服务器管理者很多Session会话,每个Session里面存储着很多关键信息,并且每个Session都有一个SessionID,而我们的Cookie中最主要就是存储着这些SessionID.后续访问该服务器的其他页面时就会带上这个SessionID,从而让服务器知道当前用户的关键信息

PS:服务器通过响应中的Set-Cookie字段将SessionID返回给Cookie

理解会话机制 (Session):

服务器同一时刻收到的请求是很多的. 服务器需要清除的区分清楚每个请求是从属于哪个用户, 就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系

会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计)

sessionId 是由服务器生成的一个 “唯一性字符串”, 从 session 机制的角度来看, 这个唯一性字符串
称为 “sessionId”. 但是站在整个登录流程中看待, 也可以把这个唯一性字符串称为 “token”.
sessionId 和 token 就可以理解成是同一个东西的不同叫法(不同视角的叫法)

  1. 当用户登陆的时候, 服务器在 Session 中新增一个新记录, 并把 sessionId / token 返回给客户端.(例如通过 HTTP 响应中的 Set-Cookie 字段返回).
  2. 客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId/ token. (例如通过 HTTP 请求中的 Cookie 字段带上).
  3. 服务器收到请求之后, 根据请求中的 sessionId / token 在 Session 信息中获取到对应的用户信息,再进行后续操作

Servlet 的 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失

Cookie 和 Session 的区别:

  1. Cookie 是客户端的机制. Session 是服务器端的机制.
  2. Cookie 和 Session 经常会在一起配合使用. 但是不是必须配合
  3. 完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是
    token / sessionId
  4. Session 中的 token / sessionId 也不需要非得通过 Cookie / Set-Cookie 传递.

三、请求 “正文” (body)

正文中的内容格式和 header 中的 Content-Type 密切相关.

罗列了三种常见的情况:

  1. application/x-www-form-urlencoded: form 表单提交的数据格式. 此时 body 的格式形如:

title=test&content=hello

  1. 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–

  1. application/json: 数据为 json 格式. body 格式形如:

{“username”:“123456789”,“password”:“xxxx”,“code”:“jw7l”,“uuid”:“d110a05ccde64b16a861fa2bddfdcd15”}


【 HTTP 请求 (Request) 】相关推荐

  1. 对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。

    这段时间折腾了哈java web应用的压力测试,部署容器是tomcat 7.期间学到了蛮多散碎的知识点,及时梳理总结,构建良好且易理解的知识架构把它们组织起来,以备忘. 对web应用开发者来说,我们很 ...

  2. python自动搜索请求失败_http请求 request失败自动重新尝试代码示例

    本文研究的主要是http请求 request失败自动重新尝试的一个例子,具体如下. 需求 最近开发一个项目,要实现的一个场景是对于某个http请求,如果请求失败,需要再自动尝试几次,并记录异常原因便于 ...

  3. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  4. 微信小程序Api发送网络请求(request)

    微信小程序发送网络请求(request) 下边的地址是微信小程序开发平台对网络请求的介绍. 微信小程序网络请求介绍 最近公司要求开发小程序,下面是我查看微信小程序文档,写的一个demo,记录下来方便以 ...

  5. CORS请求Request携带Cookie失败占用License解决方案

    文章目录 CORS请求Request携带Cookie失败占用License解决方案 起因 现象 解决过程 总结 参考 CORS请求Request携带Cookie失败占用License解决方案 起因 因 ...

  6. 封装请求 request.js

    pc vue项目 import axios from 'axios' // 要先引入弹窗ui import { MessageBox, Loading } from 'element-ui'let l ...

  7. Spring/SpringBoot 过滤器修改、获取http 请求request中的参数 和 response返回值,比如修改请求体和响应体的字符编码

    通过自定义filter,RequestWrapper,ResponseWrapper 处理请求和响应数据,比如修改请求体和响应体的字符编码 1.request 和 response 中的数据都是 存在 ...

  8. 微信小程序API之发起请求request

    一.首先考虑发起 HTTPS 网络请求. 在小程序/小游戏中使用网络相关的 API 时,需要注意下列问题 1. 服务器域名配置 每个微信小程序需要事先设置通讯域名,小程序只可以跟指定的域名与进行网络通 ...

  9. 从零开始学微信小程序(不是教程·网络请求Request·GET)

    好像文章变得越来越长了 于是决定每个主题单开一个文章 省的多图杀猫 接口 2018·10·21 其实后台和前台的对接对我来说一直是一个很玄学的东西 可能是因为缺乏基本全面的https知识 完全没办法理 ...

  10. angularjs中$http模块发送post请求request payload转form data

    背景: ionic+ angularjs+ cordova 在开发一个证书照片删除的时候,后端提供了一个post接口,需要前端将数据转化成form data.而在angularjs中,如果直接用pos ...

最新文章

  1. 为什么阿里巴巴开发手册明确说明 Arrays.asList() 不能使用其修改方法
  2. 程序员七夕如何表白:朕只爱一个皇后!(单例模式)
  3. python for循环删除
  4. How is syntax error in Vue detected - Vue的语法错误检查机制介绍
  5. java循环的嵌套执行
  6. 信息学奥赛一本通(1196:踩方格)
  7. 在ListView控件中绘底图
  8. nodejs 复制、移动文件
  9. 法国spin高等计算机学校,spin-去展网
  10. java s类型_javasript基础——数据类型与数据类型转换
  11. jQuery实用小技巧--输入框文字获取和失去焦点
  12. html注册页面多选代码,利用HTML表单标签编写一个注册页面
  13. javascript时钟代码
  14. 两个命令行应用程序的交互——使用Java的Process类完成复杂控制台程序的自动化操作(以围棋GTP协议为例)
  15. 好用的码字软件,年入百万的大神作家们都在用
  16. netty做一个posp的网络_Java网络通信基础系列-Netty实现HTTP服务
  17. QGIS二次开发01---临时绘制图层实现
  18. div从上到下从左到右自动换行显示排列
  19. c盘扩容提示簇被标记_垃圾文件正在吞噬你的C盘空间!用这四种方法,还你一个干净的C盘...
  20. 九零起航服务器(港澳服务器) 如何设置404页面

热门文章

  1. 看 Amazon 如何通过 Nitro System 构建技术优势
  2. 万能pdf转换器 V4.1
  3. Exadata 机器介绍
  4. python-获取UUID
  5. 22. Vue keycodes按键修饰符
  6. Run Commands Remotely via SSH with No Password
  7. 【历史上的今天】10 月 25 日:Windows XP 20 周年;任正非出生;图灵奖编程语言先驱诞生
  8. 做一个像人的3d人物建模需要通过什么技术和怎样的资金达成?
  9. Activiti7工作流引擎:基础篇(六) 任务监听器和流程监听器
  10. 2015定额企业取费证规费费率核定标准摘录绵建价【2016】3 号