Loading... ##1.什么是Referer `Referer` 头部包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 `Referer` 头部识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。 ##2.Referer的作用 ###防盗链 将一个http请求发给服务器后,如果服务器要求必须是某个地址或者某几个地址才能访问,而你发送的referer不符合他的要求,就会拦截或者跳转到他要求的地址,然后再通过这个地址进行访问。 比如我只允许我自己的网站访问我自己的图片服务器,那我的域名是`www.domineto.top`,那么图片服务器每次取到Referer来判断一下是不是我自己的域名`www.domineto.top`,如果是就继续访问,不是就拦截。 ###3. 拼写问题 这里我转载了一篇文章中的一部分,原文链接: [https://imququ.com/post/referrer-or-referer.html] ### HTTP 中的 Referrer HTTP 协议中有一个用来表示页面或资源来源的请求头,由 Philip Hallam-Baker 于上世纪 90 年代提出来,他当时把这个请求头叫做 `Referer`,并最终写进了 RFC1945,也就是 HTTP/1.0 协议: > The Referer request-header field allows the client to specify, for the server's benefit, the address (URI) of the resource from which the Request-URI was obtained. [via](http://tools.ietf.org/html/rfc1945#section-10.13) 有趣的是,当时这个单词被他拼错了,正确的拼写应该是 `Referrer`。但是这个错误被发现之前,已经被大量使用,如果要改过来需要所有服务端、客户端的一致配合,还有大量的代码需要排查修改。于是,HTTP 的标准制定者们决定将错就错,不改了。下面这段描述来自于 RFC2616,也就是著名的 HTTP/1.1 协议: > The Referer[sic] request-header field allows the client to specify, for the server's benefit, the address (URI) of the resource from which the Request-URI was obtained (the "referrer", although the header field is misspelled.) [via](http://tools.ietf.org/html/rfc2616#section-14.36) 可以看到,相比 HTTP/1.0,HTTP/1.1 除了加上了对这个错误的说明之外,没有其他变化。另外,那个 `[sic]` 是拉丁文里「原文如此」的意思。很多其他标准在表述 HTTP 中的 `Referer` 请求头时,都会加上 `[sic]`,避免引起读者误解。 由此可见,HTTP 标准制定者奉行实用主义,能用就行。由于 HTTP 协议继续拼错,浏览器当然只好按错的来,服务端收到的也是拼错的,所以大部分 Web Server、服务端语言或框架,都跟着拼错。举几个例子: * **Nginx**:ngx_http_referer_module - used to block access to a site for requests with invalid values in the "Referer" header field; * **PHP**:$_SERVER['HTTP_REFERER'] - The address of the page (if any) which referred the user agent to the current page; * **Django**:HttpRequest.META.HTTP_REFERER – The referring page, if any; * **ThinkJS**:Controller.referer() - 获取 referer; ### JavaScript 中的 Referrer 这里说的 JavaScript,都是针对宿主为浏览器的场景,获取到的 referrer 属性都是由浏览器提供的。这一次,浏览器们比较齐心,都采用了正确的拼写方式,没有让这个错误在 JavaScript 中延续。 例如 DOM Level 2 里定义的 `document.referrer`: > Returns the URI [[IETF RFC 2396](http://www.w3.org/TR/DOM-Level-2-HTML/references.html#RFC2396)] of the page that linked to this page. The value is an empty string if the user navigated to the page directly (not through a link, but, for example, via a bookmark). [via](http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-95229140) 最新的 Fetch API 中的 Request 接口,也有一个名为 `referrer` 的属性: > The referrer attribute's getter must return the empty string if request's referrer is no referrer, "about:client" if request's referrer is client and request's referrer, serialized, otherwise. [via](https://fetch.spec.whatwg.org/#dom-request-referrer) 更多关于 Fetch API 的介绍可以查看月影大大翻译的这篇文章:[这个API很“迷人”——(新的Fetch API)](http://www.w3ctech.com/topic/854)。 ### 其他标准中的 Referrer 其他标准,例如 [Referrer Policy](https://imququ.com/post/referrer-policy.html),也采用了正确的写法,并且明确表示不会兼容错误的拼写,例如在 [Delivery via CSP](https://w3c.github.io/webappsec-referrer-policy/#directive-referrer) 这一节写着: > Note: The directive name does not share the HTTP header's misspelling. ### 结论 HTTP 请求中的 `Referer` 是一个典型的拼写错误,历史悠久,可以预见还会一直错下去,以后 `Referer` 变成一个专有名词也说不定。所以一般涉及到读取 HTTP 请求头的场景,我们需要用 `Referer` 这种错误拼写;除此之外一般都要用 `Referrer` 这种正确的拼写。 最后修改:2019 年 04 月 24 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏