referrerpolicy-以最小的成本实现系统的图片上传

背景

系统上传图片一般有以下三种方案:

  1. 购买云存储(比如 AWS S3、阿里云 OSS、腾讯云 COS),获取图片URL
  2. 直接将图片上传到服务器,存储在本地作为静态资源
  3. 使用第三方的图片服务(比如有道、博客园),借用对方资源

结合本系统需求:自建博客尽可能减少预算,方案1放弃;方案二似乎可行,但随着图片增加会不停的占用资源,且不方便清除未使用的图片。最后决定方案三。

使用第三方图片,经常会遇到图片无法加载的问题。例如,你可能会在富文本编辑器(如 Tiptap)中直接粘贴 Markdown 格式的图片链接,如下所示:

![image](https://img.example.com/image.png)

然而,图片却无法显示,浏览器控制台报错:​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 头的作用包括:

  1. 防盗链:图片服务器可以通过检查 Referer 头,限制只有特定域名的请求才能访问资源。
  2. 流量统计:服务器可以分析 Referer 头,了解用户是从哪个页面跳转过来的。
  3. 安全防护:某些服务器会根据 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],
});
posted @ 2025-03-19 15:48  webLion200  阅读(26)  评论(0)    收藏  举报