1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
---
title: Travailler avec des fichiers
slug: Mozilla/Add-ons/WebExtensions/Working_with_files
tags:
- Guide
- WebExtensions
translation_of: Mozilla/Add-ons/WebExtensions/Working_with_files
---
<div>{{AddonSidebar()}}</div>
<p>Votre extension de navigateur peut avoir besoin de fichiers pour offrir des fonctionnalités complètes. Cet article examine les cinq mécanismes permettant de gérer les fichiers :</p>
<ul>
<li>Téléchargement de fichiers dans le dossier de téléchargement sélectionné de l'utilisateur.</li>
<li>Ouverture de fichiers à l'aide d'un sélecteur de fichiers dans une page Web.</li>
<li>Ouverture de fichiers par glisser-déposer sur une page Web.</li>
<li>Enregistrement de fichiers ou de blobs localement avec IndexedDB à l'aide de la bibliothèque idb-file-storage.</li>
<li>Transmission de fichiers à une application native sur l'ordinateur de l'utilisateur.</li>
</ul>
<p>Pour chacun de ces mécanismes, nous présentons leur utilisation avec des références à la documentation API pertinente, des guides et des exemples montrant comment utiliser l'API.</p>
<h2 id="Téléchargement_de_fichiers_avec_l'API_de_téléchargement">Téléchargement de fichiers avec l'API de téléchargement</h2>
<p>Ce mécanisme vous permet d'obtenir un fichier depuis votre site Web (ou tout emplacement que vous pouvez définir comme URL) vers l'ordinateur de l'utilisateur. La clé est {{WebExtAPIRef("downloads.download()")}}, qui, dans sa forme la plus simple, accepte une URL et télécharge le fichier de cette URL vers le dossier de téléchargement par défaut de l'utilisateur :</p>
<pre class="brush: js">browser.downloads.download({ url : ‘https://example.org/image.png’ })</pre>
<p>Vous pouvez laisser l'utilisateur télécharger à un endroit de son choix en précisant le paramètre<code>saveAs</code>.</p>
<div class="note">
<p>En utilisant <a href="/fr/docs/Web/API/URL/createObjectURL">URL.createObjectURL()</a>, vous pouvez également télécharger des fichiers et des blobs définis dans votre JavaScript, y compris le contenu local extrait de IndexedDB.</p>
</div>
<p>L'API de téléchargement fournit également des fonctionnalités pour annuler, mettre en pause, reprendre, effacer et supprimer les téléchargements, rechercher les fichiers téléchargés dans le gestionnaire de téléchargement, afficher les fichiers téléchargés dans le gestionnaire de fichiers de l'ordinateur, et ouvrir un fichier dans une application associée.</p>
<p><span id="result_box" lang="fr"><span>Pour utiliser cette API, vous devez avoir les </span></span><a href="/fr/docs/Web/API/Permissions#API_permissions">permissions API</a> "downloads" spécifiées dans votre fichier<a href="/fr/Add-ons/WebExtensions/manifest.json"> manifest.json</a>.</p>
<p>Exemple : <a href="https://github.com/mdn/webextensions-examples/tree/master/latest-download">Latest download</a><br>
API référence : <a href="/fr/Add-ons/WebExtensions/API/downloads">downloads API</a></p>
<h2 id="Ouverture_de_fichiers_dans_une_extension_avec_un_sélecteur_de_fichiers">Ouverture de fichiers dans une extension avec un sélecteur de fichiers</h2>
<p>Si vous souhaitez travailler avec un fichier de l'ordinateur de l'utilisateur, une option est de permettre à l'utilisateur de sélectionner un fichier à l'aide du navigateur de fichiers de l'ordinateur. Créez une nouvelle page ou injectez un code dans une page existante pour utiliser le type <code>file</code> de l'élément <code>input</code> HTML pour offrir à l'utilisateur un sélecteur de fichiers. Une fois que l'utilisateur a sélectionné un ou des fichiers, le script associé à la page peut accéder au contenu du fichier à l'aide du <a href="/fr/docs/Web/API/File">DOM File API</a>, de la même manière qu'une application web.</p>
<p>Exemple : <a href="https://github.com/mdn/webextensions-examples/tree/master/imagify">Imagify</a><br>
Guide : <a href="/fr/docs/Using_files_from_web_applications">Using files from web applications</a><br>
API références : <a href="/fr/docs/Web/HTML/Element/input/file">HTML input element</a> | <a href="/fr/docs/Web/API/File">DOM File API</a></p>
<div class="note">
<p>Si vous souhaitez accéder ou traiter tous les fichiers dans un dossier sélectionné, vous pouvez le faire en utilisant <code><input type="file" webkitdirectory="true"/></code>pour sélectionner le dossier et récupérer tous les fichiers qu'il contient.</p>
</div>
<h2 id="Ouverture_de_fichiers_dans_une_extension_avec_glisser-déposer"><span id="result_box" lang="fr"><span>Ouverture de fichiers dans une extension avec glisser-déposer</span></span></h2>
<p>L'API Web Drag and Drop offre une alternative à l'utilisation d'un sélecteur de fichiers. Pour utiliser cette méthode, établissez une zone de stockage qui correspond à votre interface utilisateur, puis ajoutez les récepteurs pour les évènements<a href="/fr/docs/Web/Events/dragenter"> dragenter</a> <em>(entrer)</em>,<a href="/fr/docs/Web/Events/dragover"> dragover</a> <em>(glisser)</em>, et<a href="/fr/docs/Web/Events/drop"> drop</a> <em>(déposer)</em>. <span id="result_box" lang="fr"><span>Dans le gestionnaire de l'événement "déposer", votre code peut accéder à tout fichier déposé par l'utilisateur à partir de l'objet offert par la propriété dataTransfer en utilisant</span></span> <a href="/fr/docs/Web/API/DataTransfer/files">DataTransfer.files</a>. Votre code peut alors accéder aux fichiers et les traiter en utilisant le <a href="/fr/docs/Web/API/File">DOM File API</a>.</p>
<p>Exemple : <a href="https://github.com/mdn/webextensions-examples/tree/master/imagify">Imagify</a><br>
Guides : <a href="/fr/docs/Using_files_from_web_applications">Using files from web applications</a> | <a href="/fr/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop">File drag and drop</a><br>
API référence : <a href="/fr/docs/Web/API/File">DOM File API</a></p>
<h2 id="Enregistrement_de_fichiers_de_données_localement_avec_la_bibliothèque_de_stockage_de_fichiers_IndexedDB">Enregistrement de fichiers de données localement avec la bibliothèque de stockage de fichiers IndexedDB</h2>
<p>Si votre extension doit enregistrer des fichiers localement, <a href="https://www.npmjs.com/package/idb-file-storage">idb-file-storage library</a> fournit une simple enveloppe de <a href="/fr/docs/Web/API/API_IndexedDB">IndexedDB API</a> <span id="result_box" lang="fr"><span>pour faciliter le stockage et la récupération des fichiers et des blobs</span></span> .</p>
<p>Sur Firefox, cette bibliothèque fournit également un " Promise-based API wrapper" pour l'API IDBMutableFile non standard. (L'API IDBMutableFile permet aux extensions de créer et de maintenir un fichier objet de base de données IndexedDB qui fournit une API pour lire et modifier le contenu du fichier sans charger tout le fichier dans la mémoire.)</p>
<p>Les principales caractéristiques de la bibliothèque sont les suivantes :</p>
<ul>
<li><a href="https://rpl.github.io/idb-file-storage/function/index.html#static-function-getFileStorage">getFileStorage</a> qui renvoie une instance IDBFileStorage, créant le stockage nommé s'il n'existe pas.</li>
<li><a href="https://rpl.github.io/idb-file-storage/class/src/idb-file-storage.js~IDBFileStorage.html">IDBFileStorage</a> qui fournit les méthodes pour sauvegarder et récupérer des fichiers tels que :
<ul>
<li>liste pour obtenir une liste de fichiers éventuellement filtrée dans la base de données.</li>
<li>mettre un fichier ou un blob dans la base de données.</li>
<li>récupérer un fichier ou un blob à partir de la base de données.</li>
<li>supprimer pour effacer un fichier ou un blob à partir de la base de données.</li>
</ul>
</li>
</ul>
<p>L'exemple <a href="https://github.com/mdn/webextensions-examples/tree/master/store-collected-images/webextension-plain">Store Collected Images</a> illustre comment utiliser la plupart de ces fonctionnalités. (IDBMutableFile n'est pas inclus, mais vous pouvez trouver des exemples dans le <a href="https://rpl.github.io/idb-file-storage/examples/">idb-file-storage examples</a> ainsi qu'un certain nombre d'autres exemples de la bibliothèque en action).</p>
<p>L'exemple <a href="https://github.com/mdn/webextensions-examples/tree/master/store-collected-images/webextension-plain">Store Collected Images</a> permet aux utilisateurs d'ajouter des images à une collection en utilisant une option dans le menu contextuel de l'image. Les images sélectionnées sont collectées dans une fenêtre contextuelle et peuvent être enregistrées dans une collection nommée. Un bouton de la barre d'outils ({{WebExtAPIRef("browserAction")}}) ouvre la collection dans une page de navigation, sur laquelle l'utilisateur peut visualiser et supprimer des images enregistrées, avec une option de filtrage pour réduire les choix. <a href="https://youtu.be/t6aVqMMe2Rc">Voir l'exemple en action</a>.</p>
<p>Le fonctionnement de la bibliothèque peut être compris en regardant <a href="https://github.com/mdn/webextensions-examples/blob/master/store-collected-images/webextension-plain/utils/image-store.js">image-store.js</a> dans /utils/ :</p>
<h3 id="Création_du_stockage_et_enregistrement_des_images"><span class="short_text" id="result_box" lang="fr"><span>Création du stockage et enregistrement des images</span></span></h3>
<pre class="brush: js">async function saveCollectedBlobs(collectionName, collectedBlobs) {
const storedImages = await getFileStorage({name: "stored-images"});
for (const item of collectedBlobs) {
await storedImages.put(`${collectionName}/${item.uuid}`, item.blob);
}
}</pre>
<p><code>saveCollectedBlobs</code> est appelé lorsque l'utilisateur clique sur Enregistrer dans la fenêtre contextuelle et a fourni un nom pour la collection d'images. D'abord, <code>getFileStorage</code> crée s'il n'existe pas déjà, ou récupère l' IndexedDB de la base de données "images stockées" dans l'objet <code>storedImages</code>. <code>storedImages.put</code> ajoute chaque image collectée à la base de données, sous le nom de la collection, en utilisant l'identifiant unique du blob (le nom du fichier). Si l'image en stock est identique à celle existatnt déjà dans la base de données, elle est écrasée. Si vous voulez éviter cela, interrogez la base de données d'abord en utilisant<code>imagesStore.list()</code> avec un filtre pour le nom du fichier et, si la liste renvoie un fichier, ajoutez un suffixe approprié au nom de la nouvelle image pour stocker un élément distinct.</p>
<h3 id="Récupération_des_images_stockées_pour_l'affichage">Récupération des images stockées pour l'affichage</h3>
<pre class="brush: js">export async function loadStoredImages(filter) {
const imagesStore = await getFileStorage({name: "stored-images"});
let listOptions = filter ? {includes: filter} : undefined;
const imagesList = await imagesStore.list(listOptions);
let storedImages = [];
for (const storedName of imagesList) {
const blob = await imagesStore.get(storedName);
storedImages.push({storedName, blobUrl: URL.createObjectURL(blob)});
}
return storedImages;
}
</pre>
<p><code>loadStoredImages</code> est appelé lorsque l'utilisateur clique sur la vue ou la recharge dans la page de navigation de la collection. <code>getFileStorage</code> ouvre la base de données "images stockées", puis <code>imagesStore.list</code>obtient une liste filtrée des images stockées. Cette liste est ensuite utilisée pour récupérer des images avec <code>imagesStore.get</code> et créer une liste retournée à l'interface utilisateur.</p>
<p>Notez l'utilisation de <a href="/fr/docs/Web/API/URL/createObjectURL">URL.createObjectURL(blob)</a> pour créer une URL qui fait référence au blob image. Cette URL est ensuite utilisée dans l'interface utilisateur (<a href="https://github.com/mdn/webextensions-examples/blob/master/store-collected-images/webextension-plain/navigate-collection.js">navigate-collection.js</a><a href="https://github.com/mdn/webextensions-examples/blob/master/store-collected-images/webextension-plain/navigate-collection.js">collection.js</a>) pour afficher l'image.</p>
<h3 id="Suppression_d'images_collectées">Suppression d'images collectées</h3>
<pre class="brush: js">async function removeStoredImages(storedImages) {
const imagesStore = await getFileStorage({name: "stored-images"});
for (const storedImage of storedImages) {
URL.revokeObjectURL(storedImage.blobUrl);
await imagesStore.remove(storedImage.storedName);
}
}
</pre>
<p><code>removeStoredImages</code> est appelé lorsque l'utilisateur clique sur "Delete" <em>(supprimer)</em> dans la page de navigation de la collection. À nouveau, <code>getFileStorage</code>ouvre la base de données “stored-images” et <code>imagesStore.remove</code> supprime chaque image à partir de la liste filtrée des images.</p>
<p>Notez l'utilisation de <a href="/fr/docs/Web/API/URL/revokeObjectURL">URL.revokeObjectURL()</a> pour révoquer explicitement l'URL du blob. Cela permet de libérer la mémoire allouée à l'URL. Si cela n'est pas fait, la mémoire n'est pas libérée jusqu'à ce que la page sur laquelle l'URL a été créée soit fermée. Si l'URL a été créée dans la page d'arrière-plan d'une extension, celle-ci n'est pas déchargée jusqu'à ce que l'extension soit désactivée, désinstallée ou rechargée, ce qui risque d'affecter inutilement les performances du navigateur. Si l'URL est créée dans la page d'une extension (nouvel onglet, fenêtre contextuelle ou barre latérale), la mémoire est libérée lorsque la page est fermée, mais il demeure de bonne pratique de révoquer l'URL lorsqu'elle n'est plus nécessaire.</p>
<p>Une fois que l'URL du blob a été révoquée, toute tentative de la charger entraînera une erreur. Par exemple, si l'URL du blob était utilisée comme attribut <code>SRC</code> d'un <code>IMG</code> tag, l'image ne sera pas chargée et ne sera pas visible. Il est donc recommandé de supprimer les URL de blobs révoquées des éléments HTML générés après leur révocation.</p>
<p>Exemple : <a href="https://github.com/mdn/webextensions-examples/tree/master/store-collected-images/webextension-plain">Store Collected Images</a><br>
API Référence : <a href="https://rpl.github.io/idb-file-storage/">idb-file-storage library</a></p>
<div class="note">
<p>Note: Vous pouvez également utiliser l' <a href="/fr/docs/Web/API/API_IndexedDB">IndexedDB API</a> pour stocker des données de votre extension. Cela peut être utile lorsque vous devez stocker des données qui ne sont pas bien gérées par les paires de clés / valeurs simples offertes par le DOM <a href="/fr/Add-ons/WebExtensions/API/Storage">Storage API</a>.</p>
</div>
<h2 id="Traitement_de_fichiers_dans_une_application_locale">Traitement de fichiers dans une application locale</h2>
<p>Lorsque vous avez une application native ou que vous souhaitez offrir des fonctionnalités natives supplémentaires pour le traitement des fichiers, utilisez une messagerie pour transmettre un fichier à une application native pour traitement.</p>
<p>Vous avez deux options :</p>
<ul>
<li>Messagerie basée sur la connexion. Ici, vous déclenchez le processus avec "runtime.connectNative()", qui renvoie un objet <a href="/fr/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a>. Vous pouvez ensuite transmettre un message JSON à l'application native en utilisant la fonction de port "postMessage()". En utilisant la fonction de port "onMessage.addListener()" vous pouvez lire les messages venant de l'application native. Celle-ci est ouverte, si elle ne s'exécute pas, lorsque "runtime.connectNative()" est appelé et l'application reste en cours d'exécution jusqu'à ce que l'extension appelle la fonction "Port.disconnect()" ou que la page qui s'y rattache soit fermée.</li>
<li>Messagerie sans connexion. Ici, vous utilisez "runtime.sendNativeMessage()" pour envoyer un message JSON à une nouvelle instance temporaire de l'application native. Le navigateur la ferme après avoir reçu un message de l'application native.</li>
</ul>
<p>Pour ajouter le fichier ou le blob, vous souhaitez que l'application native utilise <a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">JSON.stringify()</a>.</p>
<p>Pour utiliser cette méthode, l'extension doit demander la <a href="fr/Add-ons/WebExtensions/manifest.json/permissions"> permission</a> "nativeMessaging" dans son fichier manifest.json. Réciproquement, l'application native doit accorder l'autorisation à l'extension en incluant son ID dans le champ "allowed_extensions" de l'application "manifest".</p>
<p>Exemple : <a href="https://github.com/mdn/webextensions-examples/tree/master/native-messaging">Native Messaging</a> (illustre simplement une messagerie)<br>
Guide : <a href="/fr/Add-ons/WebExtensions/Native_messaging">Native messaging</a><br>
API référence : <a href="/fr/Add-ons/WebExtensions/API/runtime">runtime API</a></p>
|