Token导航 LogoToken导航TokenDH.com
前端设计操作浏览器github未标认证来源可访问许可证需确认审计通过

web-files-file-upload-patternsWeb 文件文件上传模式

Agent Skill

web-files-file-upload-patterns 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

269

周安装

11

GitHub Stars

5

下载量

86
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:web-files-file-upload-patterns(Web 文件文件上传模式)
来源仓库:https://github.com/agents-inc/skills
仓库路径:skills/web-files-file-upload-patterns
安装命令:
npx skills add https://github.com/agents-inc/skills --skill web-files-file-upload-patterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/agents-inc/skills --skill web-files-file-upload-patterns

简介

用于处理 GitHub 仓库、Issue、Pull Request 等代码协作信息。

  • 适合在需要围绕仓库状态、代码变更或协作事项进行整理时使用。
  • 通过 GitHub 仓库安装,支持 Codex、Claude、Cursor、Gemini CLI 等宿主。
  • 安装前需确认权限范围和维护状态,注意是否会触发联网或命令执行。
  • web-files-file-upload-patterns 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

File Upload Patterns

Quick Guide: Use drag-and-drop dropzones with fallback file inputs for uploads. Validate files client-side (MIME + magic bytes) AND server-side. For files >5MB use chunked uploads with progress tracking. Upload directly to S3 using presigned URLs to avoid server bottlenecks. Always implement proper accessibility with keyboard support and ARIA announcements. Use XHR (not fetch) for upload progress events.

<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST validate files BOTH client-side AND server-side - client validation is UX only, not security)

(You MUST use magic bytes detection for security-critical uploads - MIME types and extensions can be spoofed)

(You MUST cleanup object URLs with URL.revokeObjectURL() to prevent memory leaks)

(You MUST provide keyboard support for dropzones - Enter/Space to open file dialog)

(You MUST use presigned URLs for cloud storage uploads - never proxy large files through your server)

</critical_requirements>


Auto-detection: file upload, dropzone, drag-drop, drag and drop upload, useDropzone, TUS protocol, presigned URL, multipart upload, file validation, magic bytes, MIME type, progress indicator, upload progress, XHR upload, S3 upload, file input, aria-label upload, chunked upload, resumable upload

When to use:

  • Building file upload interfaces (single or multi-file)
  • Implementing drag-and-drop upload areas
  • Uploading to cloud storage directly from browser
  • Validating file types before upload
  • Showing upload progress with speed/ETA
  • Handling large file uploads with chunking/resumable support
  • Creating accessible file upload components

When NOT to use:

  • Server-side file processing (use backend skills)
  • File storage architecture (use infrastructure skills)
  • Video/audio streaming (use media handling skills)

Detailed Resources:


Philosophy

File uploads are deceptively complex. A simple file input works for basic cases, but production apps need validation, progress feedback, error handling, and accessibility. The key insight is that client-side validation is for UX, not security - always validate on the server too.

Core Principles:

  1. Defense in depth - Validate extension + MIME type + magic bytes + server-side
  2. Progressive enhancement - Drag-drop enhances but doesn't replace click-to-browse
  3. Direct uploads - Use presigned URLs to upload to cloud storage directly, not through your server
  4. Chunked for reliability - Large files need chunking for resumability and progress
  5. Accessibility first - Keyboard navigation and screen reader support from day one

File Size Strategy:

File SizeUpload MethodProgress UIStorage Pattern
< 5MBSingle requestSpinner or barDirect presigned PUT
5-50MBSingle requestProgress barPresigned PUT
50MB-5GBChunkedProgress + ETAMultipart presigned
> 5GBChunked + resumableProgress + ETA + pauseMultipart required

Core Patterns

Pattern 1: Drag-and-Drop Dropzone

Build a dropzone with drag-and-drop and fallback file input. Key elements:

  • Track drag state with a counter ref (not boolean) to handle nested element events
  • role="button" + tabIndex={0} + Enter/Space key handlers for keyboard access
  • Hidden <input type="file"> triggered by click/keyboard
  • Type validation via accept attribute plus runtime checking
  • Reset event.target.value = '' after selection to allow re-selecting same file
// Key structure - full implementation in examples/core.md
export function FileDropzone({ onFilesSelected, accept, multiple, disabled }: FileDropzoneProps) {
  const inputRef = useRef<HTMLInputElement>(null);
  const dragCounterRef = useRef(0); // Handles nested element drag events

  return (
    <div
      onDrop={handleDrop}
      onDragEnter={() => { dragCounterRef.current++; setState('drag-over'); }}
      onDragLeave={() => { dragCounterRef.current--; if (dragCounterRef.current === 0) setState('idle'); }}
      onClick={() => inputRef.current?.click()}
      onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') inputRef.current?.click(); }}
      role="button"
      tabIndex={disabled ? -1 : 0}
      aria-label="File upload area. Click or drag files to upload."
    >
      <input ref={inputRef} type="file" hidden aria-hidden="true" tabIndex={-1} />
    </div>
  );
}

See examples/core.md for full implementation.


Pattern 2: File List Management Hook

Track multiple files with status, progress, and preview URLs:

// use-file-list.ts - full implementation in examples/core.md
interface FileWithId {
  id: string;
  file: File;
  preview?: string;
  status: "pending" | "uploading" | "success" | "error";
  progress: number;
  error?: string;
}

export function useFileList(options: UseFileListOptions = {}) {
  const [files, setFiles] = useState<FileWithId[]>([]);

  // addFiles returns { added, rejected } with rejection reasons
  // removeFile cleans up object URLs via URL.revokeObjectURL()
  // clearFiles revokes all object URLs before clearing

  return {
    files,
    addFiles,
    removeFile,
    updateFile,
    clearFiles,
    hasFiles,
    canAddMore,
  };
}

Key: Always URL.revokeObjectURL() on remove and clear. Return rejected files with reasons for user feedback.

See examples/core.md for full hook.


Pattern 3: Upload Progress with XHR

The Fetch API does not support upload progress events. Use XHR:

// use-upload-progress.ts - full implementation in examples/progress.md
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", (event) => {
  if (event.lengthComputable) {
    const speed = calculateRollingAverageSpeed(event.loaded, performance.now());
    const remaining = (event.total - event.loaded) / speed;
    setProgress({
      loaded: event.loaded,
      total: event.total,
      percentage,
      speed,
      remainingTime: remaining,
    });
  }
});

Key: Use a rolling average (5 samples) for smooth speed display. Always provide abort capability via xhr.abort().

Note: Fetch streams measure bytes taken from your stream, not actual network transmission (Jake Archibald's analysis). A native fetch progress API is in development. Until then, use XHR.

See examples/progress.md for full hook and multi-file manager.


Pattern 4: Magic Bytes File Type Detection

MIME types and extensions can be spoofed. Read actual file bytes:

// file-type-detection.ts - full implementation in examples/validation.md
const FILE_SIGNATURES: FileSignature[] = [
  { mime: "image/jpeg", extension: "jpg", signature: [0xff, 0xd8, 0xff] },
  {
    mime: "image/png",
    extension: "png",
    signature: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],
  },
  {
    mime: "application/pdf",
    extension: "pdf",
    signature: [0x25, 0x50, 0x44, 0x46],
  }, // %PDF
  {
    mime: "application/zip",
    extension: "zip",
    signature: [0x50, 0x4b, 0x03, 0x04],
  },
];

export async function detectFileType(
  file: File,
): Promise<DetectionResult | null> {
  const HEADER_SIZE = 12;
  const buffer = await file.slice(0, HEADER_SIZE).arrayBuffer();
  const bytes = new Uint8Array(buffer);
  // Match against signatures, return { mime, extension, confidence }
}

Key: Only read first 8-12 bytes (not entire file). Office documents (.docx/.xlsx/.pptx) are ZIP files - detect by checking for word//xl//ppt/ in the first 1000 bytes.

See examples/validation.md for full detection and validator class.


Pattern 5: Direct-to-Storage Upload with Presigned URLs

Upload directly to cloud storage from the browser. The flow:

  1. Client requests presigned URL from your server (with file metadata)
  2. Server generates time-limited presigned URL and returns it
  3. Client uploads directly to storage using the presigned URL
  4. Server never touches the file bytes
// Client-side upload - full implementation in examples/s3-upload.md
export async function uploadWithPresignedPut(
  file: File,
  presignedUrl: string,
  options: {
    onProgress?: (progress: number) => void;
    abortSignal?: AbortSignal;
  } = {},
): Promise<void> {
  const xhr = new XMLHttpRequest();
  // XHR for progress + PUT to presigned URL
  xhr.open("PUT", presignedUrl);
  xhr.setRequestHeader("Content-Type", file.type);
  xhr.send(file);
}

Key: For POST uploads, add presigned fields to FormData before the file (order matters). For large files (>100MB), use multipart upload with per-part presigned URLs. Always sanitize filenames server-side.

See examples/s3-upload.md for POST/PUT uploads, multipart, and full flow hook.


Pattern 6: Chunked and Resumable Uploads

For files >100MB, split into chunks with concurrency control:

// chunked-upload.ts - full implementation in examples/resumable.md
const DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024; // 5MB

// Upload chunks in parallel with concurrency limit
// Retry failed chunks with exponential backoff
// Save progress to localStorage for browser refresh recovery
// Support pause/resume/cancel

Key: Use localStorage keyed by filename-size-lastModified to persist completed chunks. Expire stored progress after 24 hours. For standards-based resumable uploads, implement the TUS protocol (POST to create, HEAD to check offset, PATCH to upload chunks).

See examples/resumable.md for chunked uploader, localStorage persistence, and TUS client.


<red_flags>

RED FLAGS

High Priority Issues:

  • Not validating files on server - client validation can be bypassed completely
  • Trusting MIME type or extension alone - both can be spoofed; use magic bytes
  • Not cleaning up object URLs - causes memory leaks with URL.createObjectURL
  • Proxying large files through server - bottlenecks server; use presigned URLs
  • No keyboard support for dropzones - accessibility violation
  • Exposing cloud storage credentials in client code - use presigned URLs from server

Medium Priority Issues:

  • No progress feedback for large uploads - users don't know if it's working
  • Using fetch for uploads - no upload progress events; use XHR
  • Not handling upload abort - users can't cancel stuck uploads
  • Long presigned URL expiration - security risk; keep under 1 hour
  • Fake progress bars - show real progress or spinner, not fake animation

Common Mistakes:

  • Not resetting file input after selection - can't select same file twice
  • Using e.stopPropagation() without e.preventDefault() on drop - browser opens file
  • Loading entire file into memory for validation - only read first bytes
  • Creating object URLs on every render without cleanup

Gotchas & Edge Cases:

  • Safari handles drag events differently - test cross-browser
  • Mobile has no drag-drop - ensure click-to-browse works
  • CORS required for direct cloud storage uploads - configure bucket policy
  • Large files may cause browser tab to freeze - use chunked upload
  • EXIF orientation in photos - images may appear rotated (modern browsers auto-rotate for display, but manual handling needed for Canvas processing)
  • dragenter/dragleave fire for nested elements - use a counter ref, not boolean state

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md

(You MUST validate files BOTH client-side AND server-side - client validation is UX only, not security)

(You MUST use magic bytes detection for security-critical uploads - MIME types and extensions can be spoofed)

(You MUST cleanup object URLs with URL.revokeObjectURL() to prevent memory leaks)

(You MUST provide keyboard support for dropzones - Enter/Space to open file dialog)

(You MUST use presigned URLs for cloud storage uploads - never proxy large files through your server)

Failure to follow these rules will create security vulnerabilities, memory leaks, and accessibility issues.

</critical_reminders>

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.2%
按下载量换算29

Claude

30.63%
按下载量换算26

Cursor

18.45%
按下载量换算16

Gemini CLI

9.55%
按下载量换算8

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills