HTTP 协议可以说是开发者最熟悉的一个网络协议,「简单易懂」和「易于扩展」两个特点让它成为应用最广泛的应用层协议。
虽然有诸多的优点,但是在协议定义时因为诸多的博弈和限制,还是隐藏了不少暗坑,让人一不小心就会陷入其中。本文总结了 HTTP 规范中常见的几个暗坑,希望大家开发中有意识的规避它们,提升开发体验。
1.Referer
HTTP 标准把 Referrer
写成 Referer
(少些了一个 r
),可以说是计算机历史上最著名的一个错别字了。
Referer
的主要作用是携带当前请求的来源地址,常用在反爬虫和防盗链上。前段时间闹的沸沸扬扬的新浪图床挂图事件,就是因为新浪图床突然开始检查 HTTP Referer
头,非新浪域名就不返回图片,导致很多蹭流量的中小博客图都挂了。
虽然 HTTP 标准里把 Referer
写错了,但是其它可以控制 Referer
的标准并没有将错就错。
例如禁止网页自动携带 Referer
头的 标签,相关关键字拼写就是正确的:
<!-- 全局禁止发送 referrer -->
<meta name="referrer" content="no-referrer" />
还有一个值得注意的是浏览器的网络请求。从安全性和稳定性上考虑,Referer
等请求头在网络请求时,只能由浏览器控制,不能直接操作,我们只能通过一些属性进行控制。比如说 Fetch 函数,我们可以通过 referrer
和 referrerPolicy
控制,而它们的拼写也是正确的:
fetch('/page', {
headers: {
"Content-Type": "text/plain;charset=UTF-8"
},
referrer: "https://demo.com/anotherpage", // <-
referrerPolicy: "no-referrer-when-downgrade", // <-
});
一句话总结:
凡是涉及到 Referrer 的,除了 HTTP 字段是错的,浏览器的相关配置字段拼写都是正确的。
二.「灵异」的空格
1.%20
还是 +
?
这个是个史诗级的大坑,我曾经被这个协议冲突坑了一天。
开始讲解前先看个小测试,在浏览器里输入 blank test
( blank
和 test
间有个空格),我们看看浏览器如何处理的:
从动图可以看出浏览器把空格解析为一个加号「+」。
是不是感觉有些奇怪?我们再做个测试,用浏览器提供的几个函数试一下:
encodeURIComponent("blank test") // "blank%20test"
encodeURI("q=blank test") // "q=blank%20test"
new URLSearchParams("q=blank test").toString() // "q=blank+test"