图床v0.1

功能概述

图床上传器新增了“截图后直接粘贴上传”功能。

用户在电脑上截图后,只需要回到图床上传器页面,按下:

  • Windows / Linux:Ctrl + V
  • macOS:Cmd + V

页面会自动读取剪贴板中的图片,并调用原有上传逻辑完成上传。

上传成功后,仍然沿用原来的行为:

  • 自动显示上传结果
  • 自动复制图片链接
  • 支持手动点击“复制链接”
  • 继续使用原有 secret_token
  • 继续使用原有 /upload_file 上传接口

修改文件

/var/www/img-uploader/index.html

新增功能点

1. 支持剪贴板图片上传

新增了全局 paste 事件监听:

document.addEventListener('paste', e => {
  const clipboardData = e.clipboardData;
  if (!clipboardData) return;

  const items = Array.from(clipboardData.items || []);
  const filesFromItems = items
    .filter(item => item.type && item.type.startsWith('image/'))
    .map((item, index) => {
      const blob = item.getAsFile();
      if (!blob) return null;

      return createPastedImageFile(blob, index);
    })
    .filter(Boolean);

  const filesFromClipboard = Array.from(clipboardData.files || [])
    .filter(file => file.type && file.type.startsWith('image/'))
    .map((file, index) => createPastedImageFile(file, index));

  const pastedFiles = filesFromItems.length > 0 ? filesFromItems : filesFromClipboard;

  if (pastedFiles.length === 0) return;

  e.preventDefault();

  dropzone.classList.add('pastehint');
  setTimeout(() => {
    dropzone.classList.remove('pastehint');
  }, 500);

  handleFiles(pastedFiles);
});

该逻辑会从剪贴板中提取图片文件,并交给原有的 handleFiles() 函数处理。


2. 新增粘贴图片文件生成函数

新增函数 createPastedImageFile(),用于把剪贴板中的图片数据转换成可上传的 File 对象。

function createPastedImageFile(blob, index) {
  let ext = 'png';

  if (blob.type === 'image/jpeg') ext = 'jpg';
  else if (blob.type === 'image/webp') ext = 'webp';
  else if (blob.type === 'image/gif') ext = 'gif';
  else if (blob.type === 'image/bmp') ext = 'bmp';

  return new File(
    [blob],
    `paste-${Date.now()}-${index}.${ext}`,
    {
      type: blob.type || 'image/png',
      lastModified: Date.now()
    }
  );
}

生成的文件名格式为:

paste-时间戳-序号.扩展名

例如:

paste-1700000000000-0.png

3. 上传区增加粘贴提示

上传区提示文字从:

<p>把图片拖到这里,或者点击选择文件</p>

修改为:

<p>把图片拖到这里,点击选择文件,或截图后直接 Ctrl+V / Cmd+V 粘贴</p>

辅助说明文字更新为:

<div class="muted" style="margin-top:12px;">
  支持多图上传,上传成功后会自动复制链接。截图后回到这个页面,直接按 Ctrl+V / Cmd+V 即可上传。
</div>

4. 粘贴上传时增加视觉反馈

新增 CSS 样式:

.dropzone.pastehint {
  background: #064e3b;
  border-color: #34d399;
}

当用户粘贴图片时,上传区域会短暂变色,提示已经识别到粘贴操作。


5. 优化文件选择逻辑

文件选择上传后,清空 fileInput.value

fileInput.addEventListener('change', () => {
  handleFiles(fileInput.files);
  fileInput.value = '';
});

这样用户可以连续选择同一个文件进行上传测试。


6. 优化上传结果渲染方式

上传成功和失败结果改为通过 DOM 创建元素,而不是直接拼接 innerHTML

这样可以减少 HTML 注入风险,也让“复制链接”按钮的事件绑定更稳定。

上传成功渲染函数:

function renderSuccess(item, fileName, url) {
  item.textContent = '';

  const title = document.createElement('strong');
  title.className = 'success';
  title.textContent = `上传成功:${fileName}`;

  const box = document.createElement('div');
  box.className = 'result';

  const link = document.createElement('a');
  link.href = url;
  link.target = '_blank';
  link.rel = 'noopener noreferrer';
  link.textContent = url;

  const br1 = document.createElement('br');
  const br2 = document.createElement('br');

  const copyBtn = document.createElement('button');
  copyBtn.textContent = '复制链接';
  copyBtn.addEventListener('click', async () => {
    try {
      await navigator.clipboard.writeText(url);
      copyBtn.textContent = '已复制';
      setTimeout(() => {
        copyBtn.textContent = '复制链接';
      }, 1200);
    } catch (e) {
      alert('复制失败,请手动复制链接');
    }
  });

  box.appendChild(link);
  box.appendChild(br1);
  box.appendChild(br2);
  box.appendChild(copyBtn);

  item.appendChild(title);
  item.appendChild(box);
}

上传失败渲染函数:

function renderError(item, fileName, message) {
  item.textContent = '';

  const title = document.createElement('strong');
  title.className = 'error';
  title.textContent = `上传失败:${fileName}`;

  const box = document.createElement('div');
  box.className = 'result';
  box.textContent = message;

  item.appendChild(title);
  item.appendChild(box);
}

使用方式

  1. 打开图床上传器页面。
  2. 确认已经保存 secret_token
  3. 使用系统截图工具截图。
  4. 回到上传器页面。
  5. 按下 Ctrl + VCmd + V
  6. 图片会自动上传。
  7. 上传成功后,图片链接会自动复制到剪贴板。

支持的图片类型

当前会根据 MIME 类型识别以下格式:

MIME 类型 文件扩展名
image/png .png
image/jpeg .jpg
image/webp .webp
image/gif .gif
image/bmp .bmp

默认兜底格式为 .png


验证方式

修改完成后刷新页面:

Ctrl + F5

然后进行测试:

  1. 截图一张图片。
  2. 打开上传器页面。
  3. Ctrl + V
  4. 上传区域短暂变色。
  5. 上传结果区域显示上传成功。
  6. 图片链接自动复制到剪贴板。

当前效果

图床上传器现在支持三种上传方式:

  1. 点击选择图片上传
  2. 拖拽图片到上传区域上传
  3. 截图后直接粘贴上传

新增粘贴上传功能没有修改后端接口,仍然复用原有 /upload_file 接口和 secret_token 鉴权逻辑。