浏览器截屏攻略,深入浅出 Screen Capture API

0 阅读3分钟

点赞 + 关注 + 收藏 = 学会了

在 Web 开发中,实现“屏幕分享”或“页面截图”曾是一件遥不可及的事情。但随着 Screen Capture API 的成熟,开发者现在只需寥寥数行原生 JavaScript 代码,就能在浏览器中直接捕获用户屏幕内容。

Screen Capture API 是 W3C 标准的一部分,它引入了 getDisplayMedia() 方法。这套 API 的核心功能是允许网页录制用户的屏幕(包括整个桌面、特定的应用程序窗口或当前的浏览器标签页)。

它的核心原理是将屏幕内容转化为一个 MediaStream(媒体流)。你可以将这个流展示在 <video> 标签里,或者利用 <canvas> 抽离出静态的图片。

用法

要实现“截图”功能,本质上是一个“截取视频帧”的过程。

核心逻辑流程

  1. 激活权限:调用 getDisplayMedia 弹出系统授权弹窗。
  2. 承载画面:创建一个隐藏的视频容器,将实时屏幕流接入。
  3. 瞬间定格:利用 Canvas 的 drawImage 方法,捕捉视频当前时刻的画面。
  4. 资源回收:截图完成后,必须手动停止录制轨道,否则浏览器上方会一直显示“正在共享”。

我用 Vue3 代码演示一下。

<template>
  <div>
    <div 
      class="capture-area" 
      style="padding: 20px;"
    >
      <h2 class="no-screenshot">这是2级标题</h2>
      <img src="https://iili.io/fcR7gSe.md.png" alt="" style="width: 140px;">
      <p style="font-size: 16px; margin: 0;">雷猴世界~</p>
    </div>

    <!-- 截图按钮 -->
    <button @click="captureScreen">点击截图</button>
  </div>
</template>

<script setup>

async function captureScreen() {
    try {
        // 第一步:获取屏幕流(必须由用户点击触发)
        const stream = await navigator.mediaDevices.getDisplayMedia({
            video: { cursor: "always" }, 
            audio: false 
        });

        // 第二步:通过 Video 元素渲染流
        const video = document.createElement("video");
        video.srcObject = stream;

        video.onloadedmetadata = () => {
            video.play();

            // 第三步:将视频帧绘制到 Canvas 上
            const canvas = document.createElement("canvas");
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;
            const ctx = canvas.getContext("2d");
            
            // 稍作延迟确保画面已渲染
            setTimeout(() => {
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

                // 第四步:导出并下载图片
                const image = canvas.toDataURL("image/png");
                downloadImage(image);

                // 第五步:释放摄像头/屏幕资源(极其重要!)
                stream.getTracks().forEach(track => track.stop());
            }, 500);
        };
    } catch (err) {
        console.error("用户拒绝了授权或发生错误:", err);
    }
}

function downloadImage(dataUrl) {
    const link = document.createElement("a");
    link.href = dataUrl;
    link.download = `screenshot_${new Date().getTime()}.png`;
    link.click();
}

</script>

<style scoped>
.capture-area {
  width: 400px;
  box-sizing: border-box;
  border: 1px solid red;
  border-radius: 20px;
}
</style>

点击页面上的“点击截图”按钮,首次会让你授权浏览器截图,需要在系统设置里授权。

授权后回到浏览器重新截图就可以选择要截图的标签页、窗口,或者是整个屏幕。

注意事项

在实际应用中,Screen Capture API 有几条硬性红线:

约束项说明
HTTPS 协议除了 localhost,必须在安全环境下运行,否则 getDisplayMedia 不存在。
用户交互限制代码不能在页面加载时自动运行,必须由 click 等用户主动事件触发。
隐私保护浏览器无法截取受系统保护的窗口(如密码管理器、某些加密视频软件)。
资源泄露如果不调用 track.stop(),电脑的任务栏会一直显示录制图标,非常消耗性能。

Screen Capture VS 第三方库

之前介绍过 html2canvasdom-to-image-more 这两个库,它们和 Screen Capture API 的应用场景完全不同。

  • Screen Capture API:捕捉的是真实屏幕。它可以抓到浏览器之外的东西(如你的桌面、其他软件),适合做录屏工具、视频会议。
  • html2canvasdom-to-image-more:捕捉的是 DOM 结构。它通过读取 HTML/CSS 重新绘制出一个 Canvas。它不需要用户授权,但它无法捕捉浏览器之外的内容。

Screen Capture API 的出现让 Web 应用拥有了原生级的交互能力。无论是做远程协作工具,还是网页端的 Bug 反馈系统,它都是一把利器。


点赞 + 关注 + 收藏 = 学会了