当前位置 : 首页 » 文章分类 :  开发  »  HTTP

HTTP

HTTP 协议相关笔记
HTTP - MDN
https://developer.mozilla.org/zh-CN/docs/Web/HTTP
MDN 的 HTTP 文档全面且详细,质量很高,还有中文翻译,是学习 HTTP 标准非常好的工具。


HTTP1.1/RFC2616

rfc2616
https://www.ietf.org/rfc/rfc2616.txt
规定了 HTTP/1.1 协议,有时间可以详细阅读下。

DevResCollect/HTTP协议(RFC2616)中文版.pdf
https://github.com/dreamofxw/DevResCollect/blob/master/HTTP%E5%8D%8F%E8%AE%AE(RFC2616)%E4%B8%AD%E6%96%87%E7%89%88.pdf


HTTP状态码

301与302的区别

301 Moved Permanently
302 Found

301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于:
301 redirect: 301 代表永久性转移(Permanently Moved)。
302 redirect: 302 代表暂时性转移(Temporarily Moved )。

1、对用户来说
301,302对用户来说没有区别,他们看到效果只是一个跳转,浏览器中旧的URL变成了新的URL。页面跳到了这个新的url指向的地方。
2、对搜索引擎来说
301重定向是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。
302重定向是临时的重定向,搜索引擎会抓取新的内容而保留旧的网址。因为服务器返回302代码,搜索引擎认为新的网址只是暂时的。

302转向可能会有URL规范化及网址劫持的问题。可能被搜索引擎判为可疑转向,甚至认为是作弊。

当网页A用301重定向转到网页B时,搜索引擎可以肯定网页A永久的改变位置,或者说实际上不存在了,搜索引擎就会把网页B当作唯一有效目标。
301的好处是:
第一, 没有网址规范化问题。
第二, 也很重要的,网页A的PR网页级别会传到网页B。
所以,尽量要使用 301 跳转

HTTP返回码中301与302的区别
https://blog.csdn.net/qmhball/article/details/7838989


401和403的区别

401 Unauthorized
403 Forbidden

401 是没有带认证信息或者带了错误的认证信息, 这时客户端可以修改认证信息进行重试;
403 是客户端带了正确的认证信息, 但服务器认为这个认证信息对应的用户是没有对应资源的访问权限的, 因此, 在向管理员获取相关权限之前, 是没有重试的必要的.

401 Unauthorized 该HTTP状态码表示认证错误,它是为了认证设计的,而不是为了授权设计的。收到401响应,表示请求没有被认证—压根没有认证或者认证不正确—但是请重新认证和重试。(一般在响应头部包含一个WWW-Authenticate来描述如何认证)。通常由web服务器返回,而不是web应用。从性质上来说是临时的东西。(服务器要求客户端重试)

403 Forbidden 该HTTP状态码是关于授权方面的。从性质上来说是永久的东西,和应用的业务逻辑相关联。它比401更具体,更实际。收到403响应表示服务器完成认证过程,但是客户端请求没有权限去访问要求的资源。

一张图说明HTTP决策过程与状态码


HTTP 决策过程与状态码

URL原理、URL编码、URL特殊字符

JavaScript中提供了3对函数用来对Url编码以得到合法的Url,它们分别是escape / unescape, encodeURI / decodeURI和encodeURIComponent / decodeURIComponent。由于解码和编码的过程是可逆的,因此这里只解释编码的过程。

下面列出了这三个函数的安全字符(即函数不会对这些字符进行编码)

  • escape(69个):*/@+-._0-9a-zA-Z
  • encodeURI(82个):!#$&'()*+,/:;=?@-._~0-9a-zA-Z
  • encodeURIComponent(71个):!'()*-._~0-9a-zA-Z

encodeURI() 是 Javascript 中真正用来对 URL 编码的函数。它着眼于对整个URL进行编码。

URL原理、URL编码、URL特殊字符
https://blog.csdn.net/freeking101/article/details/68922983


Headers

HTTP Headers - MDN
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

HTTP 消息头允许客户端和服务器通过 request 和 response 传递附加信息。一个请求头由名称(不区分大小写)后跟一个冒号”:”,冒号后跟具体的值(不带换行符)组成。该值前面的引导空白会被忽略。

自定专用消息头可通过 X- 前缀来添加;但是这种用法被IETF在2012年6月发布的 RFC5548 中明确弃用,原因是其会在非标准字段成为标准时造成不便;其他的消息头在 IANA 注册表 中列出, 其原始内容在 RFC 4229 中定义。 此外,IANA 还维护着 被提议的新 HTTP 消息头注册表.

Connection

Connection 头(header) 决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成。

Connection: keep-alive
Connection: close

X-Forwarded-For

X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1(RFC2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC7239 (Forwarded HTTP Extension) https://tools.ietf.org/html/rfc7239 标准之中。

一般来说,X-Forwarded-For是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中

X-Forwarded-For 请求头格式非常简单,就这样:

X-Forwarded-For: client, proxy1, proxy2, ...

可以看到,XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP。

如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:

X-Forwarded-For: IP0, IP1, IP2

Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得。我们知道 HTTP 连接基于 TCP 连接,HTTP 协议中没有 IP 的概念,Remote Address 来自 TCP 连接,表示与服务端建立 TCP 连接的设备 IP,在这个例子里就是 IP3。

Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。不同语言获取 Remote Address 的方式不一样,例如 php 是 $_SERVER["REMOTE_ADDR"],Node.js 是 req.connection.remoteAddress,但原理都一样。

HTTP 请求头中的 X-Forwarded-For
https://imququ.com/post/x-forwarded-for-header-in-http.html


X-Real-IP

X-Real-IP 通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端。
需要注意的是,X-Real-IP 目前并不属于任何标准,代理和 Web 应用之间可以约定用任何自定义头来传递这个信息。

remote_addr

X-Forwarded-For和X-Real-IP只有请求存在代理时才有值,而remote_addr一直存在。

  • X-Forwarded-For:记录代理服务器的地址,每经过一个代理,该字段会追加上一个记录。格式形如:1.1.1.1, 2.2.2.2。
  • X-Real-IP:也是用来记录服务器的地址,但是和上面的不同,它不把记录添加到结尾,而是直接替换。
  • remote_addr:上一个客户端连接的地址,不存在代理就表示客户端的地址,存在代理就表示最后一个代理服务器的地址。

[COLLECT]HTTP头中X-FORWARDED-FOR、X-REAL-IP、REMOTE_ADDR这几者之间的区别
https://ixyzero.com/blog/archives/4088.html


Accept


Content-Type

Content-Type - MDN
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type

Content-Type 实体头部用于指示资源的 MIME 类型 media type 。

在响应中,Content-Type 标头告诉客户端实际返回的内容的内容类型。
浏览器会在某些情况下进行 MIME 查找,并不一定遵循此标题的值; 为了防止这种行为,可以将标题 X-Content-Type-Options 设置为 nosniff。

Content-Type 决定浏览器将以什么形式、什么编码读取这个文件。

X-Content-Type-Options 禁止MIME嗅探

X-Content-Type-Options - MDN
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/X-Content-Type-Options

X-Content-Type-Options HTTP 消息头相当于一个提示标志,被服务器用来提示客户端一定要遵循在 Content-Type 首部中对 MIME 类型 的设定,而不能对其进行修改。这就禁用了客户端的 MIME 类型嗅探行为,换句话说,也就是意味着网站管理员确定自己的设置没有问题。

该消息头最初是由微软在 IE 8 浏览器中引入的,提供给网站管理员用作禁用内容嗅探的手段,内容嗅探技术可能会把不可执行的 MIME 类型转变为可执行的 MIME 类型。在此之后,其他浏览器也相继引入了这个消息头,尽管它们的 MIME 嗅探算法没有那么有侵略性。

语法
X-Content-Type-Options: nosniff


Content-Disposition

Content-Disposition - MDN
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition

在常规的 HTTP 应答中,Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

在 multipart/form-data 类型的应答消息体中, Content-Disposition 消息头可以被用在 multipart 消息体的子部分中,用来给出其对应字段的相关信息。各个子部分由在 Content-Type 中定义的分隔符分隔。用在消息体自身则无实际意义。

普通HTTP消息中的 Content-Disposition

在 HTTP 场景中,第一个参数或者是 inline(默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示),或者是 attachment(意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将 filename 的值预填为下载后的文件名,假如它存在的话)。

Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"

比如,以下是一则可以触发”保存为”对话框的服务器应答:

200 OK
Content-Type: text/html; charset=utf-8
Content-Disposition: attachment; filename="cool.html"
Content-Length: 22

<HTML>Save me!</HTML>

multipart 消息中的 Content-Disposition

在 HTTP 场景中。第一个参数总是固定不变的 form-data;附加的参数不区分大小写,并且拥有参数值,参数名与参数值用等号(=)连接,参数值用双引号括起来。参数之间用分号(;)分隔。

Content-Disposition: form-data
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"

MIME 类型/Content-Type

MIME 类型 - MDN
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types

媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。它在 IETF RFC 6838 中进行了定义和标准化。

在 Http 协议消息头中,使用 Content-Type 头部来表示具体请求中的媒体类型信息。

IANA 的 Media Types 列表页面

互联网号码分配机构(IANA)是负责跟踪所有官方MIME类型的官方机构,您可以在媒体类型 Media Types 页面中找到最新的完整列表。

MIME 结构

type/subtype
MIME的组成结构非常简单;由类型与子类型两个字符串中间用’/‘分隔而组成。不允许空格存在。type 表示可以被分多个子类的独立类别。subtype 表示细分后的每个类型。

MIME类型对大小写不敏感,但是传统写法都是小写。

MIME 分类

类型 描述 典型示例
text 人类可读的普通文本 text/plain, text/html, text/css, text/javascript
image 表明是某种图像。 image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon
audio 表明是某种音频文件 audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav
video 表明是某种视频文件 video/webm, video/ogg
application 表明是某种二进制数据 application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf

对于 text 文件类型若没有特定的 subtype,就使用 text/plain。
类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream。

text 类型

text/html : HTML格式
text/xml : XML格式
text/plain: 数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符

image 类型

image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式

application 类型

application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
对于前端使用而言,form表单的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded

application/octet-stream

这是应用程序文件的默认值。意思是 未知的应用程序文件 ,浏览器一般不会自动执行或询问执行。
览器会像对待 设置了 HTTP 头 Content-Disposition 值为 attachment 的文件一样来对待这类文件。

很多 web 服务器使用默认的 application/octet-stream 来发送未知类型。出于一些安全原因,对于这些资源浏览器不允许设置一些自定义默认操作,导致用户必须存储到本地以使用

Multipart 类型

Multipart 类型包括

multipart/form-data
multipart/byteranges

multipart/form-data

multipart/form-data 数据被编码为一条消息,页上的每个控件对应消息中的一个部分。

在开发中很多时候需要会涉及到上传图片等服务器交互的操作 , 这基本上全部都会使用 multipart/form-data 的请求方式来完成上传。
multipart/form-data 定义在 rfc2388 中,最早的 HTTP POST 是不支持文件上传的,给编程开发带来很多问题。但是在1995年,ietf 出台了 rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以 Content-Type 的类型扩充了multipart/form-data 用以支持向服务器发送二进制数据。

因此,发送 POST 请求时候,表单 <form> 属性 enctype 共有二个值可选,这个属性管理的是表单的 MIME 编码:
application/x-www-form-urlencoded (默认值)
multipart/form-data
注:form 表单中 enctype 的默认值是 enctype=”application/x-www-form-urlencoded”

通过 form 表单提交文件操作如下:

<FORM method="POST" action="http://w.sohu.com/t2/upload.do" enctype="multipart/form-data">
    <INPUT type="text" name="city" value="Santa colo">
    <INPUT type="text" name="desc">
    <INPUT type="file" name="pic">
</FORM>

浏览器将会发送以下数据:

POST /t2/upload.do HTTP/1.1
User-Agent: SOHUWapRebot
Accept-Language: zh-cn,zh;q=0.5
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Length: 60408
Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data; name="city"

Santa colo
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="pic"; filename="photo.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary

... binary data of the jpg ...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--

请求头部的信息 boundary 这个参数是分界线的意思 , 也就是说你在请求头中指定分界线为: ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC , 那么请求体中凡是遇到这个字符串都会被视为分界线 , 这个分界线参数具体是什么你可以随意自定义。

深入解析 multipart/form-data
https://www.jianshu.com/p/29e38bcc8a1d

Multipart/form-data
https://www.jianshu.com/p/e810d1799384


上一篇 2019年运动记录

下一篇 领域驱动设计

阅读
评论
4,058
阅读预计16分钟
创建日期 2019-02-21
修改日期 2020-10-23
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论