Abandonner les URL de données dans l'élément SVG

Jun Kokatsu
Jun Kokatsu

La spécification SVG a été récemment mise à jour pour supprimer la prise en charge des URL data: dans l'élément SVG <use>. Cela améliore la sécurité de la plate-forme Web et la compatibilité entre les navigateurs, car Webkit n'accepte pas les URL data: dans l'élément SVG <use>.

Motif de la suppression

L'élément SVG <use> peut récupérer des images SVG externes et les cloner dans le document actuel. Cette fonctionnalité très performante est limitée aux images SVG de même origine. Toutefois, les URL data: sont traitées comme des ressources de même origine, ce qui a entraîné plusieurs bugs de sécurité, tels que le contournement des Trusted Types et de l'API Sanitizer. Ces bugs de sécurité ont conduit à une discussion sur la meilleure approche à adopter pour les résoudre. Les fournisseurs de navigateurs (de Mozilla et d'Apple) se sont mis d'accord sur le fait que la meilleure solution était de supprimer la prise en charge des URL data: dans l'élément SVG <use>.

Pour les sites qui utilisent des URL data: dans l'élément SVG <use>, il existe plusieurs alternatives.

Utiliser des images SVG de même origine

Vous pouvez charger des images SVG de même origine à l'aide de l'élément <use>.

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

Utiliser des images SVG intégrées

Vous pouvez référencer des images SVG intégrées à l'aide de l'élément <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>

Utiliser des images SVG avec des URL blob:

Si vous ne contrôlez pas le code HTML ou les ressources de même origine d'une page (comme les bibliothèques JavaScript), vous pouvez charger des images SVG à l'aide des URL blob: dans l'élément <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);

Exemples en ligne

Vous trouverez des exemples en direct pour ces alternatives sur GitHub.