Web referrer策略详解与防盗链图片的显示

这篇文章发布于 2023年08月29日,星期二,23:53,归类于 Web综合。 阅读 14941 次, 今日 8 次 2 条评论

 

遛狗封面图

这篇文章好好讲讲Web中的referrer策略,以及一些应用。

一、从document.referrer说起

document.referrer可以获取页面的来源信息。

在移动端,我们可以根据此属性值是否为空,来决定左上角的按钮是返回还是回到首页。

返回上一页截图示意

关于这个,之前有撰文介绍过,六年前的文章。

不过当时只是浅尝辄止,并没有深入具体的referrer策略,这一次,好好说说这个事情。

然后,referrer策略服务端也是可以设置的,但本文仅仅讨论前端部分的技术实现。

二、具体的referrer策略

在 HTTP header 中有个名为Referrer-Policy的状态,可以决定目标页面中document.referrer的返回值,以及对页面中外链资源的请求影响。

Referrer-Policy: no-referrer
Referrer-Policy: no-referrer-when-downgrade
Referrer-Policy: origin
Referrer-Policy: origin-when-cross-origin
Referrer-Policy: same-origin
Referrer-Policy: strict-origin
Referrer-Policy: strict-origin-when-cross-origin
Referrer-Policy: unsafe-url

各个支持的值及其含义如下:

no-referrer

发送的请求或调整的页面不包括任何Referer信息。

开源页面 导航到 Referrer使用
https://example.com/page anywhere (no referrer)

no-referrer-when-downgrade

当协议安全级别保持不变或提高时(HTTP→HTTP, HTTP→HTTPS, HTTPS→HTTPS),在Referer中发送源、路径和查询字符串,下降的时候(HTTPS→HTTP, HTTPS→file)不发送Referer信息。

开源页面 导航到 Referrer使用
https://example.com/page https://example.com/otherpage https://example.com/page
https://example.com/page https://www.zhangxinxu.com/code> https://example.com/page
https://example.com/page http://example.com (no referrer)

origin

Referer信息是来源页面URL地址中的origin信息(location.origin)。

开源页面 导航到 Referrer使用
https://example.com/page anywhere https://example.com/

origin-when-cross-origin

如果跨域,Referer只显示原始的域信息。

开源页面 导航到 Referrer使用
https://example.com/page https://example.com/otherpage https://example.com/page
https://example.com/page https://zhangxinxu.com https://example.com/
https://example.com/page http://example.com/page https://example.com/

same-origin

必须域名相同,否则Referer信息为空。

开源页面 导航到 Referrer使用
https://example.com/page https://example.com/otherpage https://example.com/page
https://example.com/page https://zhangxinxu.com (no referrer)

strict-origin

仅当协议安全级别保持不变时发送Referer信息,否则无Referer信息。

开源页面 导航到 Referrer使用
https://example.com/page https://zhangxinxu.com https://example.com/
https://example.com/page http://example.com (no referrer)
http://example.com/page anywhere http://example.com/

strict-origin-when-cross-origin(默认值)

域名和安全协议相同或更高的时候,Referer信息是完整地址,如果跨域,则Referer信息是原始的域信息,如果安全协议降低,Referer信息为空。

开源页面 导航到 Referrer使用
https://example.com/page https://example.com/otherpage https://example.com/page
https://example.com/page https://zhangxinxu.com https://example.com/
https://example.com/page http://example.com (no referrer)

unsafe-url

就算URL地址不安全,也发送完整的Referer信息。

开源页面 导航到 Referrer使用
https://example.com/page?q=123 anywhere https://example.com/page?q=123

其中,部分访问来源策略是最近几年才有各大现代浏览器支持的,尤其是那几个包含了origin的策略值,以目前的浏览器版本来看,大家无需担心兼容性问题,放心使用即可。

三、referrer设置的几种方法

在Web网页中,referrer设置有下面三种方法(如果还有其他的,欢迎评论补充)。

1. meta设置

例如:

<meta name="referrer" content="origin" />

或者

<meta name="referrer" content="no-referrer" />

lt;meta>元素的设置是影响整个页面的。

2. rel属性

rel属性支持名为noreferrer的属性值,注意,其中没有短横线,一般作用在链接元素上,这样,访问此链接,是不会携带referrer信息的。

<a href="https://www.cssworld.cn" rel="noreferrer">点击我不要钱</a>

rel属性其实支持非常多的属性值,有兴趣了解的,可以参见我之前的这篇文章:“HTML rel属性值释义大全”。

rel支持的属性值

不过rel属性只能设置noreferrer这一个策略,如果希望设置其他属性值,还需要使用专门的HTML属性-referrerpolicy。

<a href="https://www.cssworld.cn" referrerpolicy="same-origin">点击我的喂</a>
<a href="https://www.cssworld.cn" referrerpolicy="origin-when-cross-origin">点击我+1</a>

眼见为实,您可以狠狠地点击这里:HTML referrerpolicy属性测试demo

点击demo页面第一个链接,在目标页面的控制台输入document.referrer,可以看到是空字符串。

链接点击示意 为空示意

因为要求访问页面地址和原页面同源(同域名)。

但是点击下面一个链接,则document.referrer则有值,且是之前页面的协议+域名信息,因为origin-when-cross-origin的意思就是,跨域的时候,仅显示域名信息,而非之前页面的完整URL路径。

显示的域信息

四、应用之显示防盗链图片

很多网站,为了避免图片被外站引用,会开启防盗链。

而防盗链的原理(有些网站并不是)就是通过HTTP_REFERER判断域名来源,而做不同的处理。

所以,如果希望让自己的网站可以显示某些外站的的图片,可以通过伪造REFERER头信息,或者直接关闭REFERER信息来实现。

常用的且比较简单的一种做法就是使用 <meta> 元素。

<meta name="referrer" content="never">

此时,原本403的图片说不定就可以正常200显示了。

五、结语说明

OK,基本上以上就是本文要说的内容了。

Web中的知识都是成体系的,贯穿前端后端,就像referrer这样一个基础的知识点,牵扯到HTML属性,JS API,HTTP协议头,服务器配置,Web安全等诸多方面的知识。

一个看似简单的HTML属性的底下,可能是一座巨大的冰山。

所以,面对知识,面对学习,要时刻谦逊,海纳百川有容乃大。

好,感谢大家的阅读,欢迎

微笑美女

(本篇完)

分享到:


发表评论(目前2 条评论)

  1. zhangyuhan说道:

    捉虫,章节三,1. lt;meta> 出现转义了

  2. Hblee说道:

    关注张老师的博客很长时间了,第一次有种强烈想留言的冲动。

    感谢张老师能够在当前动不动“手撕 vue react 源码”的浮躁时代传播最纯粹的前端知识,可能这些非常细琐的知识如今并不受人重视,但作为您的忠实读者工作很多年后来看依然受益匪浅,常看常新,可以说影响了我的整个前端职业生涯。

    在这里感谢您的分享和付出!