背景
系统上传图片一般有以下三种方案:
- 购买云存储(比如 AWS S3、阿里云 OSS、腾讯云 COS),获取图片URL
- 直接将图片上传到服务器,存储在本地作为静态资源
- 使用第三方的图片服务(比如有道、博客园),借用对方资源
结合本系统需求:自建博客尽可能减少预算,方案1放弃;方案二似乎可行,但随着图片增加会不停的占用资源,且不方便清除未使用的图片。最后决定方案三。
使用第三方图片,经常会遇到图片无法加载的问题。例如,你可能会在富文本编辑器(如 Tiptap)中直接粘贴 Markdown 格式的图片链接,如下所示:

然而,图片却无法显示,浏览器控制台报错:403 Forbidden。这是因为图片服务器启用了 防盗链机制,通过检查 Referer
请求头来限制访问。当图片嵌入到你的网站时,浏览器会发送包含你的网站地址的 Referer
,导致图片服务器拒绝访问。
为了解决这个问题,我们可以使用 referrerpolicy
属性,控制浏览器是否发送 Referer
头。本文将详细介绍 referrerpolicy
的作用、使用场景以及如何在实际开发中应用它。
什么是 Referer
头?
Referer
是 HTTP 请求头的一部分,用于告诉服务器请求的来源。例如,当你在 https://example.com/page
页面中加载一张图片 https://img.example.com/image.png
时,浏览器会发送以下请求头:
httpGET /image.png HTTP/1.1
Host: img.example.com
Referer: https://example.com/page
Referer
头的作用包括:
- 防盗链:图片服务器可以通过检查
Referer
头,限制只有特定域名的请求才能访问资源。 - 流量统计:服务器可以分析
Referer
头,了解用户是从哪个页面跳转过来的。 - 安全防护:某些服务器会根据
Referer
头判断请求是否合法。
什么是 referrerpolicy
?
referrerpolicy
是一个 HTML 属性,用于控制浏览器在发送请求时是否包含 Referer
头。通过设置 referrerpolicy
,我们可以决定是否发送 Referer
头,以及发送哪些信息。
常用值
值 | 描述 |
---|---|
no-referrer |
完全不发送 Referer 头。 |
no-referrer-when-downgrade |
默认值。HTTPS 页面加载 HTTP 资源时不发送 Referer 头,其他情况发送。 |
origin |
只发送当前页面的域名(如 https://example.com ),而不是完整 URL。 |
origin-when-cross-origin |
同源请求发送完整 URL,跨域请求只发送域名。 |
same-origin |
同源请求发送 Referer 头,跨域请求不发送。 |
strict-origin |
只发送域名,且 HTTPS 页面加载 HTTP 资源时不发送。 |
strict-origin-when-cross-origin |
同源请求发送完整 URL,跨域请求只发送域名,且 HTTPS 页面加载 HTTP 资源时不发送。 |
unsafe-url |
总是发送完整 URL,即使从 HTTPS 页面加载 HTTP 资源。 |
使用场景
1. 绕过防盗链机制
当图片服务器启用了防盗链机制时,我们可以通过设置 referrerpolicy="no-referrer"
,阻止浏览器发送 Referer
头,从而绕过限制。
<img src="https://img.example.com/image.png" referrerpolicy="no-referrer">
2. 保护隐私
在某些场景下,我们可能不希望泄露当前页面的 URL。例如,当用户点击外部链接时,可以通过设置 referrerpolicy="no-referrer"
,避免发送 Referer
头。
<a href="https://external.com" referrerpolicy="no-referrer">External Link</a>
3. 减少信息泄露
在 HTTPS 页面加载 HTTP 资源时,默认会发送 Referer
头,这可能导致信息泄露。通过设置 referrerpolicy="no-referrer-when-downgrade"
,可以避免这种情况。
<img src="http://img.example.com/image.png" referrerpolicy="no-referrer-when-downgrade">
在 Tiptap 中的应用
如果你在 Tiptap 编辑器中直接粘贴 Markdown 格式的图片链接,可能会遇到 403 Forbidden 问题。可以通过以下方式解决:
1. 自定义 Image
扩展
在 Tiptap 中扩展默认的 Image
节点,添加 referrerpolicy
属性。
import { mergeAttributes } from "@tiptap/core";const CustomImage = Image.extend({addAttributes() {return {...this.parent?.(),referrerpolicy: {default: "no-referrer",},};},renderHTML({ node, HTMLAttributes }) {return ["img",mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {referrerpolicy: "no-referrer", // 强制添加 referrerpolicy}),];},
});
2. 在 Tiptap 中使用自定义扩展
将 CustomImage
添加到 Tiptap 的扩展列表中。
import { Editor } from "@tiptap/core";
import CustomImage from "./CustomImage";const editor = new Editor({extensions: [CustomImage],
});