Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

Document : méthode write()

Obsolète: Cette fonctionnalité n'est plus recommandée. Même si certains navigateurs la prennent encore en charge, elle a peut-être déjà été supprimée des standards du web, est en passe d'être supprimée ou n'est conservée qu'à des fins de compatibilité. Évitez de l'utiliser et mettez à jour le code existant si possible ; consultez le tableau de compatibilité au bas de cette page pour vous aider à prendre votre décision. Sachez que cette fonctionnalité peut cesser de fonctionner à tout moment.

Attention : Utiliser la méthode document.write() est fortement déconseillé. Évitez de l'utiliser et, si possible, remplacez-la dans le code existant.

Comme le spécification HTML elle-même le prévient (angl.) :

Cette méthode a un comportement très particulier. Dans certains cas, cette méthode peut affecter l'état de l'analyseur HTML (angl.) pendant que l'analyseur fonctionne, ce qui entraîne un DOM qui ne correspond pas à la source du document (par exemple, si la chaîne de caractères écrite est la chaîne de caractères « <plaintext> » ou « <!-- »). Dans d'autres cas, l'appel peut d'abord effacer la page actuelle, comme si document.open() avait été appelé. Dans d'autres cas encore, la méthode est simplement ignorée ou génère une exception. Les agents utilisateurs sont expressément autorisés à éviter l'exécution des éléments script insérés via cette méthode (angl.). Et pour aggraver les choses, le comportement exact de cette méthode peut dans certains cas dépendre de la latence du réseau, ce qui peut entraîner des échecs très difficiles à déboguer. Pour toutes ces raisons, l'utilisation de cette méthode est fortement déconseillée.

Attention : Cette méthode analyse les entrées comme du HTML, écrivant le résultat dans le DOM. Les API de ce type sont connues sous le nom de points d'injection, et sont potentiellement un vecteur pour des attaques de script inter-site (XSS), si l'entrée provient initialement d'un attaquant.

Vous pouvez atténuer ce risque en passant toujours des objets TrustedHTML au lieu de chaînes de caractères et en appliquant des types de confiance. Voir Considérations de sécurité pour plus d'informations.

La méthode write() de l'interface Document écrit du texte dans un ou plusieurs paramètres TrustedHTML ou chaînes de caractères dans un flux de document ouvert par document.open().

Syntaxe

js
write(markup)
write(markup, markup2)
write(markup, markup2, /* …, */ markupN)

Paramètres

markup, …, markupN

Des objets TrustedHTML ou des chaînes de caractères contenant le balisage à écrire dans le document.

Valeur de retour

Aucune (undefined).

Exceptions

InvalidStateError DOMException

La méthode a été appelée sur un document XML, ou appelée lorsque l'analyseur exécute actuellement un constructeur d'élément personnalisé.

TypeError

Une chaîne de caractères est passée comme l'un des paramètres lorsque les types de confiances sont appliqués et qu'aucune politique par défaut n'a été définie pour créer des objets TrustedHTML.

Description

document.write() analyse le texte de balisage contenu dans les objets passés en paramètres et l'insère dans le modèle d'objet du document (DOM) ouvert, dans l'ordre des paramètres fournis.

Parce que document.write() écrit dans le flux du document, appeler document.write() sur un document fermé (chargé) (sans appeler préalablement document.open()) provoque automatiquement un appel à document.open(), ce qui effacera le document.

L'exception est que si l'appel document.write() est intégré dans une balise HTML <script> en ligne, alors il ne déclenchera pas automatiquement l'appel à document.open() :

html
<script>
  document.write("<h1>Titre principal</h1>");
</script>

document.write() (et document.writeln) ne peut pas être utilisé avec XML ou XHTML, et toute tentative de le faire lèvera une exception InvalidStateError. C'est le cas si l'on ouvre un fichier local avec l'extension « .xhtml » ou pour tout document servi avec le type MIME application/xhtml+xml. Plus d'informations sont disponibles dans la FAQ XHTML du W3C (angl.).

L'utilisation de document.write() dans les scripts différés ou asynchrones sera ignorée et vous obtiendrez dans la console d'erreurs un message du type « Un appel à document.write() depuis un script externe chargé de manière asynchrone a été ignoré ».

Dans Edge uniquement, appeler document.write() plus d'une fois dans un <iframe> provoque l'erreur « SCRIPT70: Permission denied  ».

Considérations de sécurité

La méthode peut être un vecteur pour des attaques de script inter-site (XSS), où des chaînes de caractères potentiellement non sûres fournies par un·e utilisateur·ice sont injectées dans le DOM sans avoir été préalablement assainies. Même si la méthode peut empêcher l'exécution des éléments HTML <script> lorsqu'ils sont injectés dans certains navigateurs (voir Intervenir contre document.write() (angl.) pour Chrome), elle reste vulnérable à de nombreuses autres manières dont des attaquant·e·s peuvent composer du HTML pour exécuter du JavaScript malveillant.

Vous pouvez atténuer ces problèmes en passant toujours des objets TrustedHTML au lieu de chaînes de caractères, et en appliquant des types de confiance en utilisant la directive CSP require-trusted-types-for. Cela garantit que l'entrée est passée par une fonction de transformation, qui a la possibilité de nettoyer l'entrée pour supprimer les balises potentiellement dangereuses (comme les éléments <script> et les attributs de gestionnaire d'événements), avant qu'elle ne soit injectée.

Exemples

Écrire du TrustedHTML

Cet exemple utilise l'API Trusted Types pour assainir des chaînes de caractères HTML contenant des éléments HTML <script> avant de les écrire dans un document.

L'exemple affiche d'abord un texte par défaut et un bouton. Lorsque le bouton est cliqué, le document courant est ouvert, trois chaînes de caractères HTML sont converties en instances de TrustedHTML puis écrites dans le document, et le document est ensuite fermé. Cela remplace le document dans la zone d'exemple, y compris le HTML original du bouton et le JavaScript qui a effectué la mise à jour !

HTML

html
<p>Ceci est le contenu original du document.</p>
<button id="remplacer" type="button">Remplacer le contenu du document</button>

JavaScript

Nous utilisons d'abord la propriété Window.trustedTypes pour accéder à la TrustedTypePolicyFactory globale, et appelons sa méthode createPolicy() pour définir une politique nommée "docPolicy".

La nouvelle politique définit une fonction de transformation createHTML() pour créer les objets TrustedHTML que nous passerons à la méthode write(). Cette méthode peut traiter la chaîne de caractères d'entrée comme elle le souhaite : l'API Trusted Types exige seulement que l'entrée passe par une fonction de transformation de politique, sans imposer de traitement particulier.

On utilisera cette méthode pour assainir l'entrée en supprimant des éléments potentiellement dangereux tels que les balises <script> ou les attributs gestionnaires d'évènements. L'assainissement est difficile à faire correctement, aussi ce processus utilise généralement une bibliothèque tierce réputée telle que DOMPurify (angl.).

Pour la démonstration, nous implémentons ici un « assainisseur » rudimentaire qui remplace les symboles < dans les balises d'ouverture et de fermeture script par le caractère &lt;.

js
const policy = trustedTypes.createPolicy("docPolicy", {
  createHTML(string) {
    return string
      .replace("<script", "&lt;script")
      .replace("</script", "&lt;/script");
  },
});

On peut ensuite utiliser la méthode TrustedTypePolicy.createHTML() sur la politique retournée pour créer des objets TrustedHTML à partir de nos chaînes de caractères d'entrée. Ces objets sont ensuite passés à la fonction write() lorsque l'utilisateur·ice clique sur le bouton.

js
const entreeUne = "<h1>Dehors avec l'ancien</h1>";
const entreeDeux = "<p>dedans avec le nouveau !</p>";
const entreeTrois = "<script>alert('evil afoot')<" + "/script>";
const remplacer = document.querySelector("#remplacer");

remplacer.addEventListener("click", () => {
  document.open();
  document.write(
    policy.createHTML(entreeUne),
    policy.createHTML(entreeDeux),
    policy.createHTML(entreeTrois),
  );
  document.close();
});

Résultats

Pressez le bouton et constatez que les éléments HTML en lesquels nous avons confiance (dans cet exemple) sont injectés, mais que l'élément non fiable <script> est désormais rendu comme du texte brut.

Écrire des chaînes de caractères

Ceci est identique à l'exemple précédent, sauf que les types de confiance ne sont pas utilisés ni appliqués. Nous écrivons des chaînes de caractères non assainies, ce qui peut ouvrir une voie à des attaques XSS.

L'exemple affiche d'abord un texte par défaut et un bouton. Lorsque le bouton est cliqué, le document courant est ouvert, trois chaînes de caractères HTML sont écrites dans le document, puis le document est fermé. Cela remplace le document dans la zone d'exemple, y compris le HTML original du bouton et le JavaScript qui a effectué la mise à jour.

HTML

html
<p>Du contenu de document original.</p>
<button id="remplacer" type="button">Remplacer le contenu du document</button>

JavaScript

js
const remplacer = document.querySelector("#remplacer");

const entreeUne = "<h1>Dehors avec l'ancien</h1>";
const entreeDeux = "<p>dedans avec le nouveau !</p>";
const entreeTrois = "<script>alert('evil afoot')<" + "/script>";

remplacer.addEventListener("click", () => {
  document.open();
  document.write(entreeUne, entreeDeux, entreeTrois);
  document.close();
});

Résultats

Appuyez sur le bouton et constatez que tous les éléments HTML sont injectés. Cela inclut l'élément HTML <script>, qui dans une application réelle aurait pu exécuter un code nuisible.

Spécifications

Specification
HTML
# dom-document-write-dev

Compatibilité des navigateurs

Voir aussi