Migracja z adresów URL danych w elemencie SVG

Jun Kokatsu
Jun Kokatsu

Specyfikacja SVG została niedawno zaktualizowana, aby usunąć obsługę adresów URL data: w elemencie SVG <use>. Poprawia to bezpieczeństwo platformy internetowej oraz kompatybilność między przeglądarkami, ponieważ Webkit nie obsługuje adresów URL data: w elemencie SVG <use>.

Powód usunięcia

Element SVG <use> może pobrać zewnętrzne obrazy SVG i sklonować je do bieżącego dokumentu. Jest to zaawansowana funkcja, dlatego jest ograniczona do obrazów SVG z tego samego źródła. Jednak adresy URL data: są traktowane jako zasoby o tym samym pochodzeniu, co spowodowało kilka błędów związanych z bezpieczeństwem, takich jak obejście zaufanych typówinterfejsu Sanitizer API. Te błędy dotyczące bezpieczeństwa doprowadziły do dyskusji na temat najlepszego sposobu ich rozwiązania. Usługodawcy przeglądarek (MozillaApple) doszli do porozumienia, że najlepszym rozwiązaniem jest usunięcie obsługi adresów URL data: w elemencie SVG <use>.

W przypadku witryn, które używają adresów URL data: w elemencie SVG <use>, istnieje kilka alternatyw.

Używanie obrazów SVG z tej samej domeny

Obrazy SVG z tego samego źródła możesz wczytywać za pomocą elementu <use>.

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

Używanie wbudowanych obrazów SVG

Obrazy SVG wbudowane możesz odwoływać za pomocą elementu <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>

Używanie obrazów SVG z adresami blob:

Jeśli nie masz kontroli nad kodem HTML strony ani zasobami z tego samego źródła (np. bibliotekami JavaScript), możesz wczytywać obrazy SVG za pomocą adresów URL blob: w elemencie <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);

Przykłady na żywo

Przykłady na żywo tych alternatywnych rozwiązań znajdziesz na GitHubie.