4 điểm bởi GN⁺ 2024-09-02 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp

Web Clipboard và cách lưu trữ dữ liệu

  • Sử dụng Web Clipboard API

    • Khi dán nội dung được sao chép từ một website vào Google Docs, định dạng vẫn được giữ nguyên, nhưng nếu dán vào VS Code thì chỉ có văn bản được dán vào
    • Clipboard lưu trữ thông tin dưới nhiều biểu diễn khác nhau gắn với các kiểu MIME
    • Đặc tả clipboard của W3C yêu cầu phải hỗ trợ ba kiểu dữ liệu: text/plain, text/html, image/png
  • Sử dụng Async Clipboard API

    • Cách đọc một biểu diễn cụ thể:
      const items = await navigator.clipboard.read();
      for (const item of items) {
        if (item.types.includes("text/html")) {
          const blob = await item.getType("text/html");
          const html = await blob.text();
          // Xử lý HTML...
        }
      }
      
    • Cách ghi nhiều biểu diễn vào clipboard:
      const textBlob = new Blob(["Hello, world"], { type: "text/plain" });
      const htmlBlob = new Blob(["Hello, <em>world<em>"], { type: "text/html" });
      const clipboardItem = new ClipboardItem({ [textBlob.type]: textBlob, [htmlBlob.type]: htmlBlob });
      await navigator.clipboard.write([clipboardItem]);
      
  • Các kiểu dữ liệu khác

    • Nếu cố ghi dữ liệu JSON vào clipboard thì sẽ xảy ra lỗi:
      const json = JSON.stringify({ message: "Hello" });
      const blob = new Blob([json], { type: "application/json" });
      const clipboardItem = new ClipboardItem({ [blob.type]: blob });
      await navigator.clipboard.write([clipboardItem]);
      
    • Kiểu application/json không được hỗ trợ
  • Thuộc tính isTrusted

    • Thuộc tính isTrusted cho biết sự kiện có được dispatch bởi user agent hay không
    • Chỉ có thể ghi dữ liệu vào clipboard từ các sự kiện đáng tin cậy
  • Clipboard Event API

    • Có thể đọc/ghi dữ liệu bằng thuộc tính clipboardData trong các sự kiện copy, cut, paste
    • Cách ghi dữ liệu JSON vào clipboard:
      document.addEventListener("copy", (e) => {
        e.preventDefault();
        const json = JSON.stringify({ message: "Hello" });
        e.clipboardData.setData("application/json", json);
      });
      
  • Lịch sử của clipboardData

    • Async Clipboard API được bổ sung vào năm 2017, nhưng clipboardData là một tính năng lâu đời hơn rất nhiều
    • clipboardData lần đầu được giới thiệu trong Internet Explorer 4 vào năm 1997
  • Script không đáng tin cậy

    • Script không đáng tin cậy chỉ có thể ghi các kiểu dữ liệu bị giới hạn vào clipboard
    • Nếu cố ghi dữ liệu vào clipboard từ một sự kiện không đáng tin cậy thì sẽ thất bại
  • Tạo nút sao chép

    • Các ứng dụng web như Google Docs dùng document.execCommand("copy") để kích hoạt một sự kiện sao chép đáng tin cậy
    • Cách này cho phép ghi các kiểu dữ liệu tùy ý vào clipboard ngay cả trong sự kiện click
  • Tạo nút dán

    • execCommand("paste") hoạt động khác nhau tùy theo trình duyệt và hệ điều hành
    • Safari yêu cầu người dùng xác nhận, còn Chrome và Edge chỉ hỗ trợ trên Windows
  • Sao chép và dán của Figma

    • Figma dùng biểu diễn HTML để lưu dữ liệu vào clipboard
    • Dữ liệu được mã hóa base64 và nhúng vào biểu diễn HTML trước khi lưu vào clipboard
  • Web Custom Formats (Pickling)

    • Được hỗ trợ trên các trình duyệt dựa trên Chromium từ năm 2022
    • Cho phép ứng dụng web ghi các kiểu dữ liệu tùy chỉnh thông qua Async Clipboard API
    • Ví dụ:
      const json = JSON.stringify({ message: "Hello, world" });
      const jsonBlob = new Blob([json], { type: "application/json" });
      const clipboardItem = new ClipboardItem({ [`web ${jsonBlob.type}`]: jsonBlob });
      navigator.clipboard.write([clipboardItem]);
      

Tổng hợp của GN⁺

  • Bài viết này khám phá Web Clipboard API và cách dữ liệu được lưu trữ
  • Giải thích sự khác biệt giữa Async Clipboard API và Clipboard Event API
  • Phân tích cách Google Docs và Figma triển khai sao chép/dán
  • Giới thiệu đề xuất Web Custom Formats (Pickling)
  • Cung cấp thông tin hữu ích cho web developer và giúp hiểu rõ các giới hạn của Clipboard API

Chưa có bình luận nào.

Chưa có bình luận nào.