上回我写了一篇文章介绍「Referrer Policy」,有小伙伴看完后问我:Referrer 这个单词到底怎么拼,为什么有时候中间有两个 r,有时候只有一个?

是的,这是一个很有趣的问题,这里就给有疑惑的同学们科普下。

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

有趣的是,当时这个单词被他拼错了,正确的拼写应该是 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/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] 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

最新的 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

更多关于 Fetch API 的介绍可以查看月影大大翻译的这篇文章:这个API很“迷人”——(新的Fetch API)

其他标准中的 Referrer

其他标准,例如 Referrer Policy,也采用了正确的写法,并且明确表示不会兼容错误的拼写,例如在 Delivery via CSP 这一节写着:

Note: The directive name does not share the HTTP header's misspelling.

结论

HTTP 请求中的 Referer 是一个典型的拼写错误,历史悠久,可以预见还会一直错下去。也许以后 Referer 会变成一个专有名词也说不定。所以,一般涉及到读取 HTTP 请求头的场景,我们需要用 Referer 这种错误拼写;除此之外一般都要用 Referrer 这种正确的拼写。

本文链接:https://imququ.com/post/referrer-or-referer.html参与评论 »

Referrer 还是 Referer?的更多相关文章

  1. referrer vs referer

    http request里面是referer 其实是http规范拼写错了,正确的拼写应该是referrer

  2. 秋天的第一份“干货” I Referer 防盗链,为什么少了个字母 R?

    Referer 为什么叫 Referer?它代表什么意思?在诸多防盗链竞争中它有什么优势? 今天,在聊 Referer 防盗链之前,先来聊聊我们在现实生活中常常碰到的推荐人(Referrer)信息. ...

  3. Express4.x常用API(二):Request

    这是第二篇了,打算每天都拿些时间去详细的看看文档来自学下express吧,接下来就开始了,这次依然是有选择性的找API根据自己的理解翻译过来,方便日后开发时候的自己查阅,由于水平有限,大概也会在使用过 ...

  4. 关于启用 HTTPS 的一些经验分享

    https://imququ.com/post/sth-about-switch-to-https.html 随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS. ...

  5. Nodejs Express 4.X 中文API 2--- Request篇

    相关阅读: Express 4.X API 翻译[一] --  Application篇 Express4.XApi 翻译[二] --  Request篇 Express4.XApi 翻译[三] -- ...

  6. Struts2文件上传方式与上传失败解决方式

    首先将几个对象弄出来第一个 上传页面第二个 上传action第三个 startut2配置文件 我的文字描述不是很好,但是终归是自己写出来的,后来我在网上看到一篇关于文件上传描述的非常清楚的文章, 链接 ...

  7. Express4.x API (二):Request (译)

    写在前面 最近学习express想要系统的过一遍API,www.expressjs.com是express英文官网(进入www.epxressjs.com.cn发现也是只有前几句话是中文呀~~),所以 ...

  8. nodejs express 学习

    nodejs的大名好多人应该是听过的,而作为nodejs web 开发的框架express 大家也应该比较熟悉. 记录一下关于express API 的文档: express() 创建express ...

  9. Express详解

    express() 创建一个express应用程序 var express = require('express'); var app = express(); app.get('/', functi ...

随机推荐

  1. golang sha1 signature

    package models import ( "crypto/hmac" "crypto/sha1" "encoding/base64" ...

  2. oracle12c及PLSQL Developer安装全程记录

    一.登陆oracle下载页面  http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 下 ...

  3. BeyondCompare常用功能图解

    http://jingyan.baidu.com/article/066074d68f847ec3c31cb05a.html http://lovesoo.org/use-file-compariso ...

  4. Java调用Lua脚本(LuaJava使用、安装及Linux安装编译)

    依赖包(附件有下载): 包名 类型 操作系统 luajava-1.1.jar jar ALL libluajava-1.1.so .so linux luajava-1.1.dll .dll wind ...

  5. python 如何判断对象是否为类(class)

    if type(att).__name__ == 'classobj':     pass else: pass

  6. hdu 1520Anniversary party(简单树形dp)

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  7. java设计模式之——代理模式

    1,什么是代理模式? 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 2,策略模式有什么好处? 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象 ...

  8. 利用js_API 运行对html文档元素的属性的CRUD操作

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. html系列教程--p param progress rp rt ruby script select small source

    <p> 标签:用户段落划分或折行的标签 <param> 标签:param 元素允许您为插入 XHTML 文档的对象规定 run-time 设置,也就是说,此标签可为包含它的 & ...

  10. 利用汇编查看C++函数调用

    这篇文章的内容是一个老生常谈的问题----> 函数是如何被调用的. 本文用汇编代码研究函数调用的过程,参数调用的方式,函数值的返回. 1. 函数是如何实现调用的 函数的调用是用call 和 re ...