You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为react-quill编辑器添加带防下载功能的视频标签

解决React-Quill视频添加防下载(controlsList="nodownload")的问题

问题分析

直接插入<video>标签无效的核心原因是:React-Quill依赖Quill的Blot系统管理编辑器内容,默认的video embed blot不会渲染额外自定义属性;而clipboard.convert会触发完整的HTML解析转换流程,同步操作耗时较长,导致了性能警告。

解决方案:自定义Video Blot

通过扩展Quill的默认Video Blot,直接控制渲染后的<video>标签属性,同时避免低效的HTML转换操作。

1. 自定义Video Blot组件

在组件文件顶部、React组件定义前添加以下代码,覆盖Quill默认的视频渲染逻辑:

import Quill from 'quill';

// 引入Quill原生的Video Blot
const Video = Quill.import('formats/video');

class CustomVideo extends Video {
  static create(value) {
    // 调用父类方法创建基础video节点
    const node = super.create(value);
    // 添加防下载属性
    node.setAttribute('controlsList', 'nodownload');
    // 配置你需要的其他属性
    node.setAttribute('width', '100%');
    node.setAttribute('min-height', '400px');
    node.setAttribute('controls', '');
    return node;
  }
}

// 注册自定义Blot,覆盖原生video格式
Quill.register(CustomVideo, true);

2. 修改原有的videoHandler

无需再使用clipboard.convert,直接用自定义Blot插入视频,优化性能同时保留原有业务逻辑:

const videoHandler = () => {
  if (!quillRef.current) return;
  const editor = quillRef.current.getEditor();
  if (!editor) return;
  
  const range = editor.getSelection();
  const value = prompt('Please paste the video URL here.');
  
  if (!value) return;
  if (!value.includes('myService.com')) {
    alert('Only videos from myService.com domain are allowed.');
    return;
  }

  // 直接插入自定义的video embed,无需HTML转换
  editor.insertEmbed(range.index, 'video', value, 'user');
};

方案优势

  • 自定义Blot直接控制<video>标签渲染,确保controlsList="nodownload"属性被正确添加;
  • 跳过clipboard.convert的HTML解析步骤,消除同步耗时操作,解决性能警告;
  • 保留Quill原生的内容管理逻辑,不会破坏编辑器的格式一致性。

额外注意事项

  • controlsList="nodownload"仅在Chrome、Edge等Chromium内核浏览器生效,Firefox和Safari不支持该属性,如需全浏览器级别的防下载,需配合后端签名、视频流加密等方案;
  • 若使用Quill v2.x版本,Blot的API略有差异,需调整继承方式(比如改为继承BlockEmbed)。

内容的提问来源于stack exchange,提问作者Airlangga Fidiyanto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:52:47