מעבר מכתובות URL של נתונים ברכיב SVG

יון קוקטסו
יוני קוקאטסו

מפרט SVG עודכן לאחרונה כדי להסיר את התמיכה ב-data: כתובות URL ברכיב SVG <use>. הפעולה הזו משפרת את האבטחה של פלטפורמת האינטרנט ואת התאימות בין הדפדפנים, כי Webkit לא תומך בכתובות URL מסוג data: ברכיב <use> של SVG.

הסיבה להסרה

רכיב SVG <use> יכול לאחזר תמונות SVG חיצוניות ולשכפל אותו למסמך הנוכחי. זו יכולת רבת-עוצמה, ולכן היא מוגבלת לתמונות SVG ממקור זהה. עם זאת, כתובות URL של data: מטופלות כמשאבים מאותו מקור שגרמו לכמה באגים באבטחה, כמו עקיפה של סוגים מהימנים ו-Sanitizer API. הבאגים האלה הובילו לדיון לגבי הגישה הטובה ביותר לפתרון שלהם. והגענו להסכמה בקרב ספקי הדפדפנים (מ-Mozilla ומ-Apple) לפיה הדרך הטובה ביותר היא להסיר את התמיכה בכתובות URL מסוג data: ברכיב SVG <use>.

לאתרים שמשתמשים בכתובות URL מסוג data: ברכיב <use> של SVG, יש כמה חלופות.

שימוש בתמונות SVG ממקור זהה

אפשר לטעון תמונות SVG ממקור זהה באמצעות רכיב <use>.

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

שימוש בתמונות SVG מוטבעות

אפשר להפנות לתמונות SVG מוטבעות באמצעות רכיב <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>

יש להשתמש בתמונות SVG עם blob: URL

אם אין לכם שליטה על משאבי ה-HTML או המקור הזהה של הדף (כמו ספריות JavaScript), תוכלו לטעון תמונות SVG באמצעות כתובות URL מסוג blob: ברכיב <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);

דוגמאות של שידורים חיים

אתם יכולים למצוא דוגמאות בזמן אמת לחלופות האלה ב-GitHub.