aboutsummaryrefslogtreecommitdiff
path: root/files/fr/mozilla/add-ons/webextensions/content_scripts
diff options
context:
space:
mode:
Diffstat (limited to 'files/fr/mozilla/add-ons/webextensions/content_scripts')
-rw-r--r--files/fr/mozilla/add-ons/webextensions/content_scripts/index.html474
1 files changed, 474 insertions, 0 deletions
diff --git a/files/fr/mozilla/add-ons/webextensions/content_scripts/index.html b/files/fr/mozilla/add-ons/webextensions/content_scripts/index.html
new file mode 100644
index 0000000000..293dd44785
--- /dev/null
+++ b/files/fr/mozilla/add-ons/webextensions/content_scripts/index.html
@@ -0,0 +1,474 @@
+---
+title: Scripts de contenu
+slug: Mozilla/Add-ons/WebExtensions/Content_scripts
+tags:
+ - Add-ons
+ - JavaScript
+ - WebExtensions
+translation_of: Mozilla/Add-ons/WebExtensions/Content_scripts
+---
+<div>{{AddonSidebar}}</div>
+
+<p>Un script de contenu (<em>content script</em> en anglais) est une partie de votre extension qui s’exécute dans le contexte d’une page web donnée (par opposition aux scripts d’arrière-plan qui font partie de l'extension, ou aux scripts qui font partie du site Web lui-même, tels que ceux chargés en utilisant l'élément {{HTMLElement("script")}}).</p>
+
+<p>Les <a href="/fr/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">scripts d'arrière-plan</a> peuvent accéder à l'ensemble des <a href="/fr/Add-ons/WebExtensions/API">API WebExtension</a> mais ils ne peuvent pas accéder directement au contenu des pages web. Aussi, si votre extension doit manipuler le contenu des pages web, vous devrez utiliser les scripts de contenu.</p>
+
+<p>Tout comme les scripts habituellement chargés par les pages web classiques, les scripts de contenu peuvent lire et modifier le contenu de leurs pages en utilisant les API DOM standard.</p>
+
+<p>Les scripts de contenu ne peuvent accéder qu'à <a href="#API WebExtensions">un sous-ensemble des API WebExtension</a>, mais ils peuvent <a href="#communication_background">communiquer avec les scripts d'arrière-plan</a> grâce à un système de messages et ainsi accéder indirectement aux API WebExtension.</p>
+
+<div class="note">
+<p>Notez que les scripts de contenu sont bloqués sur les domaines suivants :</p>
+
+<ul style="display: grid;">
+ <li>accounts-static.cdn.mozilla.net</li>
+ <li>accounts.firefox.com</li>
+ <li>addons.cdn.mozilla.net</li>
+ <li>addons.mozilla.org</li>
+ <li>api.accounts.firefox.com</li>
+ <li>content.cdn.mozilla.net</li>
+ <li>content.cdn.mozilla.net</li>
+ <li>discovery.addons.mozilla.org</li>
+ <li>input.mozilla.org</li>
+ <li>install.mozilla.org</li>
+ <li>oauth.accounts.firefox.com</li>
+ <li>profile.accounts.firefox.com</li>
+ <li>support.mozilla.org</li>
+ <li>sync.services.mozilla.com</li>
+ <li>testpilot.firefox.com</li>
+</ul>
+
+<p>If you try to inject a content script into a page in these domains, it will fail and the page will log a <a href="/en-US/docs/Web/HTTP/CSP">CSP</a> error.</p>
+
+<p>Because these restrictions include addons.mozilla.org, users may attempt to use your extension immediately after installation—only to find that it doesn't work! You may want to add an appropriate warning, or an <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/onboarding_upboarding_offboarding_best_practices">onboarding page</a> to move users away from addons.mozilla.org.</p>
+</div>
+
+<div class="note">
+<p>Les valeurs ajoutées à la portée globale d'un script de contenu avec <code>var foo</code> ou <code>window.foo = "bar"</code> peuvent disparaître à cause du bogue <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1408996">1408996</a>.</p>
+</div>
+
+<h2 id="Charger_des_scripts_de_contenu">Charger des scripts de contenu</h2>
+
+<p>Il est possible de charger un script de contenu dans une page web de trois manières différentes :</p>
+
+<ol>
+ <li><strong>Lors de la phase d'installation, pour les pages qui correspondent à certains motifs d'URL :</strong> en utilisant la clé <code><a href="/fr/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code> dans le fichier <code>manifest.json</code>, vous pouvez demander au navigateur de charger un script de contenu chaque fois que le navigateur charge une page dont l'URL <a href="/fr/Add-ons/WebExtensions/Match_patterns">correspond à un motif donné</a>.</li>
+ <li><strong>Lors de l'exécution, pour les pages qui correspondent à certains motifs d'URL :</strong> en utilisant l'API {{WebExtAPIRef("contentScripts")}}, vous pouvez demander au navigateur de charger un script de contenu chaque fois que le navigateur charge une page dont l'URL <a href="/fr/Add-ons/WebExtensions/Match_patterns">correspond à un motif donné</a>. Cette méthode est la version dynamique de la première méthode.</li>
+ <li><strong>Lors de l'exécution, pour certains onglets spécifiques :</strong> en utilisant la méthode  <code><a href="/fr/Add-ons/WebExtensions/API/Tabs/executeScript">tabs.executeScript()</a></code>, vous pouvez charger un script de contenu dans un onglet spécifique quand vous le souhaitez (par exemple lorsqu'un utilisateur clique sur un <a href="/fr/Add-ons/WebExtensions/Browser_action">bouton d'action du navigateur</a>).</li>
+</ol>
+
+<p>Il n'y a qu'une seule portée globale pour chaque <em>frame</em> et pour chaque extension. Cela signifie que les variables d'un script de contenu peuvent être accédées directement par un autre script de contenu, indépendamment de la manière dont le script de contenu a été chargé.</p>
+
+<p>À l'aide des méthodes (1) et (2), vous ne pouvez charger des scripts que dans des pages dont les URL peuvent être représentées par un <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">motif de correspondance</a>.</p>
+
+<p>En utilisant la méthode (3), vous pouvez également charger des scripts dans des pages packagées avec votre extension, mais vous ne pouvez pas charger des scripts dans des pages privilégiées du navigateur (comme <code><a>about:debugging</a></code> ou <code><a>about:addons</a></code>).</p>
+
+<h2 id="Environnement_des_scripts_de_contenu">Environnement des scripts de contenu</h2>
+
+<h3 id="Accès_au_DOM">Accès au DOM</h3>
+
+<p>Les scripts de contenu peuvent accéder et modifier le DOM de la page à la manière des scripts classique. Ils peuvent également observer tout changement du DOM effectué par les scripts de la page.</p>
+
+<p>Cependant, les scripts de contenu reçoivent une « vue propre du DOM ». Cela signifie que :</p>
+
+<ul>
+ <li>Les scripts de contenu ne peuvent pas accéder aux variables JavaScript définies par les scripts de la page.</li>
+ <li>Si un script de page redéfinit une propriété intrinsèque du DOM, le script de contenu verra la version originale de cette propriété et non la version redéfinie.</li>
+</ul>
+
+<p>Dans Firefox, ce comportement s'appelle <a href="/fr/docs/Mozilla/Tech/Xray_vision">Vision Xray</a>.</p>
+
+<p>Prenons par exemple la page web suivante :</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta http-equiv="content-type" content="text/html; charset=utf-8" /&gt;
+ &lt;/head&gt;
+
+ &lt;body&gt;
+ &lt;script src="page-scripts/page-script.js"&gt;&lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>Le script « page-script.js » est écrit ci-dessous :</p>
+
+<pre class="brush: js">// page-script.js
+
+// ajouter un élément au DOM
+var p = document.createElement("p");
+p.textContent = "Ce paragraphe a été ajouté par un script de la page.";
+p.setAttribute("id", "page-script-para");
+document.body.appendChild(p);
+
+// définition d’une nouvelle propriété pour la fenêtre
+window.toto = "Cette variable globale a été ajoutée par un script de la page.";
+
+// redéfinition de la fonction intégrée window.confirm()
+window.confirm = function() {
+ alert("Ce script de page peut aussi redéfinir ’confirm’.");
+}</pre>
+
+<p>Et maintenant une extension injecte ce script de contenu dans la page :</p>
+
+<pre class="brush: js">// content-script.js
+
+// peut accéder au DOM et le modifier
+var pageScriptPara = document.getElementById("page-script-para");
+pageScriptPara.style.backgroundColor = "blue";
+
+// ne peut pas voir les propriétés ajoutées par un script de la page
+console.log(window.toto); // non défini
+
+// voit la forme originale des propriétés redéfinies
+window.confirm("Êtes-vous sûr ?"); // appelle la méthode window.confirm() originale</pre>
+
+<p>L'inverse est également vrai : les scripts de la page ne peuvent pas voir les propriétés JavaScript ajoutées par les scripts de contenu.</p>
+
+<p>Ceci signifie que le script de contenu peut compter sur un comportement prévisible des propriétés du DOM et n'a pas à se soucier d'un éventuel conflit entre les variables qu'il définit et celles des scripts de page.</p>
+
+<p>Une des conséquences pratiques de ce comportement est que les scripts de contenu n’ont accès à aucune des bibliothèques JavaScript chargées par la page. Par exemple, si la page inclut jQuery, le script de contenu ne pourra pas le voir.</p>
+
+<p>Si un script de contenu veut utiliser une bibliothèque JavaScript, alors la bibliothèque doit être injectée en tant que script de contenu aux côtés du script de contenu qui veut l’utiliser.</p>
+
+<pre class="brush: json">"content_scripts": [
+ {
+ "matches": ["*://*.mozilla.org/*"],
+ "js": ["jquery.js", "content-script.js"]
+ }
+]</pre>
+
+<div class="blockIndicator note">
+<p><strong>Note:</strong> Firefox <em>fournis</em> certaines API qui permettent aux scripts de contenu d'accéder aux objets JavaScript créés par les scripts de page et d'exposer leurs propres objets JavaScript aux scripts de page.</p>
+
+<p>Voir <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts">Partage d'objets avec des scripts de page</a> pour plus de détails.***</p>
+</div>
+
+<h3 id="Les_API_WebExtension_accessibles"><a id="API WebExtensions" name="API WebExtensions">Les API WebExtension accessibles</a></h3>
+
+<p>En plus des API standard du DOM, les scripts de contenu peuvent utiliser les API WebExtension suivantes :</p>
+
+<p>Depuis l'API <code><a href="/fr/Add-ons/WebExtensions/API/extension">extension</a></code> :</p>
+
+<ul>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/extension#getURL()">getURL()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/extension#inIncognitoContext">inIncognitoContext</a></code></li>
+</ul>
+
+<p>Depuis l'API <code><a href="/fr/Add-ons/WebExtensions/API/runtime">runtime</a></code> :</p>
+
+<ul>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/runtime#connect()">connect()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/runtime#getManifest()">getManifest()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/runtime#getURL()">getURL()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/runtime#onConnect">onConnect</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/runtime#onMessage">onMessage</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/runtime#sendMessage()">sendMessage()</a></code></li>
+</ul>
+
+<p>Depuis l'API <code><a href="/fr/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a></code> :</p>
+
+<ul>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/i18n/getMessagee">getMessage()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/i18n/getAcceptLanguages">getAcceptLanguages()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/i18n/getUILanguage">getUILanguage()</a></code></li>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/i18n/detectLanguage">detectLanguage()</a></code></li>
+</ul>
+
+<p>A partir des <code><a href="/fr/Add-ons/WebExtensions/API/menus">menus</a></code>:</p>
+
+<ul>
+ <li><code><a href="/fr/Add-ons/WebExtensions/API/menus/getTargetElement">getTargetElement</a></code></li>
+</ul>
+
+<p>L'ensemble des propriétés et méthodes de l'API <code><a href="/fr/Add-ons/WebExtensions/API/storage">storage</a></code>.</p>
+
+<h3 id="XHR_et_Fetch">XHR et Fetch</h3>
+
+<p>Les scripts de contenu peuvent effectuer des requêtes en utilisant les API classiques  <code><a href="/fr/docs/Web/API/XMLHttpRequest">window.XMLHttpRequest</a></code> et <code><a href="/fr/docs/Web/API/Fetch_API">window.fetch()</a></code>.</p>
+
+<p>Les scripts de contenu obtiennent les mêmes privilèges interdomaines que le reste de l'extension : si l'extension a demandé un accès interdomaine pour un domaine à l'aide de la clé <code><a href="/fr/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code> dans le fichier <code><a href="/fr/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a></code>, ses scripts de contenu auront également accès à ce domaine.</p>
+
+<p>Ceci est accompli en exposant des instances XHR et <em>fetch</em> privilégiées dans le script de contenu. Cela a pour effet secondaire de ne pas définir les en-têtes <code><a href="/fr/docs/Web/HTTP/Headers/Origin">Origin</a></code> et <code><a href="/fr/docs/Web/HTTP/Headers/Referer">Referer</a></code> tels que la page elle-même l'aurait fait. Cela est souvent préférable afin d'éviter que la requête révèle la différence d'origine. À partir de Firefox 58, les extensions qui doivent exécuter des requêtes se comportant comme si elles étaient envoyées par le contenu lui-même peuvent utiliser <code>content.XMLHttpRequest</code> et <code>content.fetch()</code>. Pour les extensions visant une compatibilité entre les navigateurs, il est nécessaire de vérifier la présence de ces API avant de les utiliser.</p>
+
+<h2 id="Communication_avec_les_scripts_darrière-plan"><a id="communication_background" name="communication_background">Communication avec les scripts d'arrière-plan</a></h2>
+
+<p>Bien que les scripts de contenu ne puissent pas utiliser la totalité des API WebExtension, ils peuvent communiquer avec les scripts d'arrière-plan de l'extension via l'API de messagerie et ont donc indirectement accès aux mêmes API que ces derniers.</p>
+
+<p>Par défault, il existe deux moyens de communication entre les scripts d'arrière-plan et les scripts de contenu : vous pouvez envoyer des messages un par un, avec des réponses optionelles, ou vous pouvez établir une connexion continue entre les scripts, et utiliser cette connexion pour échanger des messages.</p>
+
+<h3 id="Un_message_à_la_fois">Un message à la fois</h3>
+
+<p>Pour envoyer un message à la fois, vous pouvez utiliser les API suivantes :</p>
+
+<table class="fullwidth-table standard-table">
+ <thead>
+ <tr>
+ <th scope="row"></th>
+ <th scope="col">Dans le script de contenu</th>
+ <th scope="col">Dans les scripts d'arrière-plan</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th scope="row">Envoyer un message</th>
+ <td><code><a href="/fr/Add-ons/WebExtensions/API/runtime#sendMessage()">browser.runtime.sendMessage()</a></code></td>
+ <td><code><a href="/fr/Add-ons/WebExtensions/API/Tabs/sendMessage">browser.tabs.sendMessage()</a></code></td>
+ </tr>
+ <tr>
+ <th scope="row">Recevoir un message</th>
+ <td><code><a href="/fr/Add-ons/WebExtensions/API/runtime/onMessage">browser.runtime.onMessage</a></code></td>
+ <td><code><a href="/fr/Add-ons/WebExtensions/API/runtime#onMessage">browser.runtime.onMessage</a></code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Par exemple, voici un script de contenu qui écoute les évènements de clic sur une page web. Si le clic était sur un lien, il envoie un message à la page d'arrière-plan avec l'URL cible :</p>
+
+<pre class="brush: js">// content-script.js
+
+window.addEventListener("click", notifyExtension);
+
+function notifyExtension(e) {
+ if (e.target.tagName != "A") {
+ return;
+ }
+ browser.runtime.sendMessage({"url": e.target.href});
+}</pre>
+
+<p>Le script d'arrière-plan écoute les messages et affiche une notification en utilisant l'API <code><a href="/fr/Add-ons/WebExtensions/API/notifications">notification</a></code> :</p>
+
+<pre class="brush: js">// background-script.js
+
+browser.runtime.onMessage.addListener(notify);
+
+function notify(message) {
+ browser.notifications.create({
+ "type": "basic",
+ "iconUrl": browser.extension.getURL("link.png"),
+ "title": "Vous avez cliqué sur un lien !",
+ "message": message.url
+ });
+}
+</pre>
+
+<p>Ce code d'exemple est légèrement dérivé de l'exemple <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> sur GitHub.</p>
+
+<h3 id="Les_messages_en_flux_continu">Les messages en flux continu</h3>
+
+<p>L'envoi de messages distincts peut vite devenir lourd si de nombreux messages sont envoyés entre les scripts d'arrière plan et les scripts de contenu.</p>
+
+<p>L'une des alternatives possibles est d'établir une connexion longue durée entre les deux scripts et d'utiliser cette connexion afin d'échanger des messages.</p>
+
+<p>De chaque côté (contenu d'une part, arrière-plan d'autre part), les scripts possèdent un objet <code><a href="/fr/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> dont ils peuvent se servir pour échanger des messages.</p>
+
+<p>Pour créer la connexion :</p>
+
+<ul>
+ <li>L'un des côtés se tient à l'écoute des connexions avec <a href="/fr/Add-ons/WebExtensions/API/runtime/onConnect"> </a><code><a href="/fr/Add-ons/WebExtensions/API/runtime/onConnect">runtime.onConnect</a></code>.</li>
+ <li>L'autre côté appelle <code><a href="/fr/Add-ons/WebExtensions/API/tabs/connect">tabs.connect()</a></code> (pour se connecter à un script de contenu) ou <code><a href="/fr/Add-ons/WebExtensions/API/runtime/connect">runtime.connect()</a></code> (pour se connecter à un script d'arrière plan). Ces deux méthodes renvoient un objet <code><a href="/fr/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code>.</li>
+ <li>Le gestionnaire d'évènement <code><a href="/fr/Add-ons/WebExtensions/API/runtime/onConnect">runtime.onConnect</a></code> reçoit alors en argument un objet <code><a href="/fr/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> qui lui est propre.</li>
+</ul>
+
+<p>Une fois que chaque côté possède son propre port, ils peuvent échanger en utilisant <code>runtime.Port.postMessage()</code> pour envoyer des message et <code>runtime.Port.onMessage</code> pour en recevoir.</p>
+
+<p>Par exemple, dès le chargement, ce script de contenu :</p>
+
+<ul>
+ <li>se connecte au script d'arrière plan et stocke l'objet <code>Port</code> dans une variable <code>myPort</code></li>
+ <li>écoute des messages sur <code>myPort</code>, et les enregistre.</li>
+ <li>envoie des messages au script d'arrière plan via <code>myPort</code>, quand l'utlisateur clique sur le document.</li>
+</ul>
+
+<pre class="brush: js">// content-script.js
+
+var myPort = browser.runtime.connect({name:"port-from-cs"});
+myPort.postMessage({greeting: "ici le script de contenu"});
+
+myPort.onMessage.addListener(function(m) {
+ console.log("Dans le script de contenu, réception d'un message du script d'arrière-plan");
+ console.log(m.greeting);
+});
+
+document.body.addEventListener("click", function() {
+ myPort.postMessage({greeting: "clic sur la page !"});
+});</pre>
+
+<p>Le script d'arrière plan qui correspond ·</p>
+
+<ul>
+ <li>Écoute les tentatives de connexion depuis le script de contenu.</li>
+ <li>Quand il reçoit une tentative de connexion :
+ <ul>
+ <li>Enregistre le port dans une variable nommée <code>portFromCS</code></li>
+ <li>Envoie un message au script de contenu en utilisant le port</li>
+ <li>Commence à écouter les messages reçus sur le port et les enregistre.</li>
+ </ul>
+ </li>
+ <li>Envoie des messages au script de contenu en utilisant <code>portFromCS</code>, quand l'utilisateur clique sur l'action navigateur de l'add-on</li>
+</ul>
+
+<pre class="brush: js">// background-script.js
+
+var portFromCS;
+
+function connected(p) {
+ portFromCS = p;
+ portFromCS.postMessage({greeting: "salut, script de contenu !"});
+ portFromCS.onMessage.addListener(function(m) {
+ console.log("Dans le script d'arrière-plan, réception d'un message du script de contenu.")
+ console.log(m.greeting);
+ });
+}
+
+browser.runtime.onConnect.addListener(connected);
+
+browser.browserAction.onClicked.addListener(function() {
+ portFromCS.postMessage({greeting: "clic sur le bouton !"});
+});
+</pre>
+
+<h4 id="Scripts_de_contenu_multiples">Scripts de contenu multiples</h4>
+
+<p>Si plusieurs scripts de contenu communiquent en même temps, vous pouvez stocker chaque connexion dans un tableau.</p>
+
+<ul>
+</ul>
+
+<pre class="brush: js">// background-script.js
+
+var ports = [];
+
+function connected(p) {
+ ports[p.sender.tab.id] = p;
+ //...
+}
+
+browser.runtime.onConnect.addListener(connected)
+
+browser.browserAction.onClicked.addListener(function() {
+ ports.forEach(p =&gt; {
+ p.postMessage({greeting: "clic sur le bouton !"})
+ })
+});</pre>
+
+<ul>
+</ul>
+
+<h2 id="Communiquer_avec_la_page_web">Communiquer avec la page web</h2>
+
+<p>Bien que les scripts de contenu ne puissent (par défaut) accéder aux objets créés par les scripts de page, ils peuvent cependant communiquer avec les scripts de page en utilisant les API <code><a href="/fr/docs/Web/API/Window/postMessage">window.postMessage</a></code> et <code><a href="/fr/docs/Web/API/EventTarget/addEventListener">window.addEventListener</a></code> du DOM.</p>
+
+<p>Par exemple :</p>
+
+<pre class="brush: js">// page-script.js
+
+var messenger = document.getElementById("from-page-script");
+
+messenger.addEventListener("click", messageContentScript);
+
+function messageContentScript() {
+ window.postMessage({
+ direction: "from-page-script",
+ message: "Message de la page"
+ }, "*");</pre>
+
+<pre class="brush: js">// content-script.js
+
+window.addEventListener("message", function(event) {
+ if (event.source == window &amp;&amp;
+ event.data &amp;&amp;
+ event.data.direction == "from-page-script") {
+ alert("Le script de contenu a reçu ce message : \"" + event.data.message + "\"");
+ }
+});</pre>
+
+<p>Pour un exemple complet et fonctionnel, <a href="https://mdn.github.io/webextensions-examples/content-script-page-script-messaging.html">visitez la page de démo sur Github</a> et suivez les instructions.</p>
+
+<div class="warning">
+<p>Notez que vous devez être très prudent lorsque vous interagissez avec du contenu Web non fiable de cette manière. Les extensions sont du code privilégié qui peut avoir de puissantes capacités et les pages Web hostiles peuvent facilement les amener à accéder à ces capacités.</p>
+
+<p>Pour donner un exemple trivial, supposons que le code du script de contenu qui reçoit le message ressemble à ceci :</p>
+
+<pre class="brush: js">// content-script.js
+
+window.addEventListener("message", function(event) {
+ if (event.source == window &amp;&amp;
+ event.data.direction &amp;&amp;
+ event.data.direction == "from-page-script") {
+ eval(event.data.message);
+ }
+});</pre>
+
+<p>Maintenant, le script de page peut exécuter n'importe quel code avec tous les privilèges du script de contenu.</p>
+</div>
+
+<h2 id="Utilisation_de_eval_dans_les_scripts_de_contenu">Utilisation de <code>eval()</code> dans les scripts de contenu</h2>
+
+<p>Dans Chrome, {{jsxref("Objets_globaux/eval","eval()")}} exécute toujours le code dans le contexte du script de contenu et pas dans le contexte de la page.</p>
+
+<p>Dans Firefox :</p>
+
+<ul>
+ <li>Si vous appelez <code>eval()</code>, le code est exécuté dans le contexte du <strong>script de contenu</strong></li>
+ <li>Si vous appelez <code>window.eval()</code>, le code est exécute dans le contexte de la <strong>page</strong>.</li>
+</ul>
+
+<p>Par exemple, considérons un script de contenu comme ceci  :</p>
+
+<pre class="brush: js">// content-script.js
+
+window.eval('window.x = 1;');
+eval('window.y = 2');
+
+console.log(`Dans le script de contenu, window.x: ${window.x}`);
+console.log(`Dans le script de contenu, window.y: ${window.y}`);
+
+window.postMessage({
+ message: "check"
+}, "*");</pre>
+
+<p>Ce code crée simplement des variables x et y en utilisant <code>window.eval()</code> et <code>eval()</code> puis enregistre leurs valeurs et envoie un message à la page.</p>
+
+<p>À la réception du message, le script de page enregistre les mêmes variables :</p>
+
+<pre class="brush: js">window.addEventListener("message", function(event) {
+ if (event.source === window &amp;&amp; event.data &amp;&amp; event.data.message === "check") {
+ console.log(`Dans le script de la page, window.x: ${window.x}`);
+ console.log(`Dans le script de la page, window.y: ${window.y}`);
+ }
+});</pre>
+
+<p>Dans Chrome, cela produira le résultat suivant :</p>
+
+<pre>Dans le script de contenu, window.x: 1
+Dans le script de contenu, window.y: 2
+Dans le script de la page, window.x: undefined
+Dans le script de la page, window.y: undefined</pre>
+
+<p>Dans Firefox, on aura le résultat suivant :</p>
+
+<pre>Dans le script de contenu, window.x: undefined
+Dans le script de contenu, window.y: 2
+Dans le script de la page, window.x: 1
+Dans le script de la page, window.y: undefined</pre>
+
+<p>La même chose s'applique pour <code><a href="/fr/docs/Web/API/WindowTimers/setTimeout">setTimeout()</a></code>, <code><a href="/fr/docs/Web/API/WindowTimers/setInterval">setInterval()</a></code>, et <code><a href="/fr/docs/Web/JavaScript/Reference/Objets_globaux/Function">Function()</a></code>.</p>
+
+<div class="blockIndicator warning">
+<p><span id="result_box" lang="fr"><span>Lorsque vous exécutez du code dans le contexte de la page, l'avertissement précédent reste nécessaire </span></span>: <span id="result_box" lang="fr"><span>l'environnement de la page est contrôlé par des pages web potentiellement malveillantes qui peuvent redéfinir les objets avec lesquels vous interagissez</span> </span>:</p>
+
+<pre class="brush: js">// page.js redéfinit console.log
+
+var original = console.log;
+
+console.log = function() {
+  original(true);
+}
+</pre>
+
+<pre class="brush: js">// content-script.js appelle la version redéfinie
+
+window.eval('console.log(false)');
+</pre>
+</div>