解决图片加载 403 错误(防盗链)

Posted by YuHo Wang on 2020-03-17

问题

html 中通过 img 标签引入图片地址,报 403 错误,而这张图片的地址单独复制出来在浏览器是能打开的。如下图:

upload successful

解决方案

在页面 head 头部添加下面这行代码:

1
2
<!-- 隐藏发送请求时请求头表示来源的 referrer 字段。 -->
<meta name="referrer" content="no-referrer">

原因

  • http 请求体的 header 中有一个 referrer 字段,用来表示发起 http 请求的源地址信息,这个 referrer 信息是可以省略但是不可修改的,就是说你只能设置是否带上这个 referrer 信息,不能定制 referrer 里面的值。
  • 服务器端在拿到这个 referrer 值后就可以进行相关的处理,比如图片资源,可以通过 referrer 值判断请求是否来自本站,若不是则返回 403 或者重定向返回其他信息,从而实现图片的防盗链。上面出现403就是因为,请求的是别人服务器上的资源,但把自己的 referrer 信息带过去了,被对方服务器拦截返回了403。
  • 在前端可以通过 meta 来设置 referrer policy(来源策略)。针对上面的 403 情况的解决方法,就是把 referrer 设置成 no-referrer,这样发送请求不会带上 referrer 信息,对方服务器也就无法拦截了。
  • 浏览器中 referrer 默认的值是 no-referrer-when-downgrade,就是除了降级请求的情况以外都会带上 referrer 信息。降级请求是指 https 协议的地址去请求 http 协议,所以上面 403 的情况还有另一种解决方法就是,请求的图片地址换成 http 协议,自己的地址使用 http 协议,这样降级请求也不会带上 referrer。

局部处理

有时候有另外的需求需要请求时发送 referrer,这个时候在 meta 上全局修改 referrer 的设置就不太合适了。

此时,可以在 <a>、<area>、<img>、<iframe>、<script> 或者 <link> 元素上的 referrerpolicy 属性为其设置独立的请求策略。

1
<a href="http://example.com" referrerpolicy="origin">

另外也可以在 <a>、<area> 或者 <link> 元素上将 rel 属性设置为 noreferrer。

1
<a href="http://example.com" rel="noreferrer">

参考文章