Di chuyển khỏi các URL dữ liệu trong phần tử SVG

Jun Kokatsu
Jun Kokatsu

Thông số kỹ thuật của SVG đã được cập nhật gần đây để ngừng hỗ trợ các URL data: trong phần tử <use> của SVG. Điều này giúp tăng khả năng bảo mật của nền tảng Web cũng như khả năng tương thích giữa các trình duyệt vì Webkit không hỗ trợ URL data: trong phần tử SVG <use>.

Lý do xóa liên kết

Phần tử SVG <use> có thể tìm nạp hình ảnh SVG bên ngoài và sao chép hình ảnh đó vào tài liệu hiện tại. Đây là một khả năng mạnh mẽ nên chỉ có thể sử dụng hình ảnh SVG có cùng nguồn gốc. Tuy nhiên, các URL data: được coi là tài nguyên có cùng nguồn gốc gây ra một số lỗi bảo mật, chẳng hạn như bỏ qua Loại đáng tin cậyAPI Sanitizer. Những lỗi bảo mật này đã giúp chúng tôi thảo luận về phương pháp tốt nhất để giải quyết chúng. Sau đó, chúng tôi đã đi đến sự thống nhất giữa các nhà cung cấp trình duyệt (từ MozillaApple) rằng cách tốt nhất để tiếp tục là ngừng hỗ trợ các URL data: trong phần tử SVG <use>.

Có một số phương án thay thế đối với các trang web dùng URL data: trong phần tử SVG <use>.

Dùng hình ảnh SVG có cùng nguồn gốc

Bạn có thể tải hình ảnh SVG có cùng nguồn gốc bằng cách sử dụng phần tử <use>.

<div class="icon">
  <svg width="1em" height="1em">
    <use xlink:href="svgicons.svg#user-icon"></use>
  </svg>
</div>

Dùng hình ảnh SVG cùng dòng

Bạn có thể tham chiếu hình ảnh SVG cùng dòng bằng cách sử dụng phần tử <use>.

<svg style="display:none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol id="user-icon" viewBox="0 0 32 32">
      <path d="M25.333 9.335c0 5.153-4.179 9.333-9.333 9.333s-9.333-4.18-9.333-9.333c0-5.156 4.179-9.335 9.333-9.335s9.333 4.179 9.333 9.335zM23.203 18.908c-2.008 1.516-4.499 2.427-7.203 2.427-2.707 0-5.199-0.913-7.209-2.429-5.429 2.391-8.791 9.835-8.791 13.095h32c0-3.231-3.467-10.675-8.797-13.092z">
    </symbol>
    <!-- And potentially many more icons -->
  </defs>
</svg>

<div class="icon">
  <svg width="1em" height="1em">
    <use xlink:href="#user-icon"></use>
  </svg>
</div>

Dùng hình ảnh SVG với blob: URL

Nếu không có quyền kiểm soát các tài nguyên HTML hoặc tài nguyên có cùng nguồn gốc của một trang (chẳng hạn như thư viện JavaScript), bạn có thể tải hình ảnh SVG bằng cách sử dụng URL blob: trong phần tử <use>.

const svg_content = `<svg style="display:none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
      <symbol id="user-icon" viewBox="0 0 32 32">
        <path d="M25.333 9.335c0 5.153-4.179 9.333-9.333 9.333s-9.333-4.18-9.333-9.333c0-5.156 4.179-9.335 9.333-9.335s9.333 4.179 9.333 9.335zM23.203 18.908c-2.008 1.516-4.499 2.427-7.203 2.427-2.707 0-5.199-0.913-7.209-2.429-5.429 2.391-8.791 9.835-8.791 13.095h32c0-3.231-3.467-10.675-8.797-13.092z">
      </symbol>
      <!-- And potentially many more icons -->
    </defs>
  </svg>`;
const blob = new Blob([svg_content], {type: 'image/svg+xml'});
const url = URL.createObjectURL(blob);
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
use.setAttribute('href', url + '#user-icon');
svg.appendChild(use);
document.body.appendChild(svg);

Ví dụ về nội dung trực tiếp

Bạn có thể tìm thấy ví dụ trực tiếp cho các phương án thay thế này trên GitHub.