Objets partagés

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

Un objet partagé, parfois appelé cookie Flash, est un fichier de données qui peut être créé sur votre ordinateur par les sites que vous visitez. Les objets partagés servent le plus souvent à optimiser la navigation sur le Web, par exemple en vous permettant de personnaliser l’aspect d’un site Web que vous consultez fréquemment.

A propos des objets partagés

Les objets partagés fonctionnent comme des cookies de navigation. La classe SharedObject permet de stocker des données sur le disque dur local de l’utilisateur et d’appeler ces données pendant la même session ou dans le cadre d’une session ultérieure. Les applications peuvent accéder uniquement à leurs propres données SharedObject, et ce, uniquement si elles sont exécutées sur le même domaine. Les données ne sont pas transmises au serveur et les applications exécutées dans d’autres domaines ne peuvent pas y accéder. En revanche, les applications du même domaine sont en mesure d’y accéder.

Comparaison des objets partagés avec les cookies

Les cookies et les objets partagés sont très similaires. Comme la plupart des programmateurs Web connaissent le fonctionnement des cookies, la comparaison des cookies et des objets SharedObjects locaux peut s’avérer utile.

Les cookies conformes au standard RFC 2109 possèdent habituellement les propriétés suivantes :

  • Ils possèdent une date d’expiration, souvent fixée par défaut à la fin d’une session.

  • Ils sont désactivables par le client en fonction de sites spécifiques.

  • La limite totale de cookies est de 300, avec 20 cookies maximum par site.

  • Leur taille est habituellement limitée à 4 Ko chacun.

  • Ils sont parfois considérés comme une menace à la sécurité et sont, par conséquent, parfois désactivés sur le client.

  • Ils sont stockés dans un emplacement spécifié par le navigateur client.

  • Ils sont transmis du client au serveur via HTTP.

    Par contre, les objets partagés possèdent les propriétés suivantes :

  • Ils n’expirent pas par défaut.

  • Par défaut, leur taille est limitée à 100 Ko chacun.

  • Ils peuvent enregistrer des types de données simples (comme String, Array et Date).

  • Ils sont stockés à un emplacement spécifié par l’application (dans le répertoire de base de l’utilisateur).

  • Ils ne sont jamais transmis entre le client et le serveur.

A propos de la classe SharedObject

La classe SharedObject permet de créer et de supprimer des objets partagés, ainsi que de détecter la taille actuelle d’un objet SharedObject en cours d’utilisation.

Création d’un objet partagé

Pour créer un objet SharedObject , faites appel à la méthode SharedObject.getLocal() , dont la syntaxe est la suivante :

SharedObject.getLocal("objectName" [, pathname]): SharedObject

L’exemple suivant crée un objet partagé dénommé mySO :

public var mySO:SharedObject; 
mySO = SharedObject.getLocal("preferences");

Cette opération crée un fichier sur l’ordinateur du client dénommé preferences.sol.

Le terme local fait référence à l’emplacement de l’objet partagé. Dans ce cas, Adobe® Flash® Player enregistre le fichier SharedObject localement dans le répertoire de base du client.

A la création d’un objet partagé, Flash Player crée un nouveau répertoire pour l’application et le domaine dans son sandbox. Il crée également un fichier *.sol qui enregistre les données SharedObject. L’emplacement par défaut de ce fichier est un sous-répertoire du répertoire de base de l’utilisateur. Le tableau suivant indique les emplacements par défaut de ce répertoire :

Système d’exploitation

Emplacement

Windows 95/98/ME/2000/XP

c:/Documents and Settings/username/Application Data/Macromedia/Flash Player/#SharedObjects

Windows Vista/Windows 7

c:/Users/username/AppData/Roaming/Macromedia/Flash Player/#SharedObjects

Macintosh OS X

/Users/username/Library/Preferences/Macromedia/Flash Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol

Linux/Unix

/home/username/.macromedia/Flash_Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol

Sous le répertoire #SharedObjects se trouve un répertoire nommé de façon aléatoire. Sous ce dernier se trouve un répertoire correspondant au nom d’hôte, puis le chemin vers l’application et finalement le fichier *.sol.

Par exemple, si vous demandez un application nommée MyApp.swf sur l’hôte local et dans un sous-répertoire nommé /sos, Flash Player enregistre le fichier *.sol à l’emplacement suivant sur Windows XP:

c:/Documents and Settings/fred/Application Data/Macromedia/Flash Player/#SharedObjects/KROKWXRK/#localhost/sos/MyApp.swf/data.sol
Remarque : si vous ne fournissez pas de nom dans la méthode SharedObject.getLocal() , Flash Player nomme le fichier undefined.sol.

Par défaut, Flash peut enregistrer des objets SharedObject persistants localement, d’une taille maximale de 100 Ko par domaine. Cette valeur est configurable par l’utilisateur. Lorsque l’application tente d’enregistrer un objet partagé d’une taille supérieure à 100 Ko, Flash Player affiche la boîte de dialogue Stockage local, qui permet à l’utilisateur d’autoriser ou de refuser une augmentation du volume de stockage local pour le domaine qui demande l’accès.

Spécification d’un chemin

Le paramètre facultatif pathname permet de spécifier l’emplacement du fichier SharedObject . Ce fichier doit être un sous-répertoire du répertoire SharedObject de ce domaine. Par exemple, si vous demandez une application sur l’hôte local et spécifiez ce qui suit :

mySO = SharedObject.getLocal("myObjectFile","/");

Flash Player écrit le fichier SharedObject dans le répertoire /#localhost (ou /localhost si l’application est hors ligne). Cela s’avère utile si vous souhaitez plusieurs applications sur le client pour pouvoir accéder au même objet partagé. Dans ce cas, le client peut exécuter deux applications Flex, qui spécifient un chemin vers l’objet partagé qui est la racine du domaine ; le client peut ensuite accéder au même objet partagé à partir des deux applications. Pour partager des données entre plusieurs applications sans persistance, vous pouvez utiliser l’objet LocalConnection.

Si vous spécifiez un répertoire inexistant, Flash Player ne crée pas de fichier SharedObject.

Ajout de données à un objet partagé

Vous ajoutez des données à un fichier *.sol d’objet SharedObject à l’aide de sa propriété data . Pour ajouter de nouvelles données à l’objet partagé, utilisez la syntaxe suivante :

sharedObject_name.data.variable = value;

L’exemple suivant ajoute les propriétés userName , itemNumbers et adminPrivileges et leurs valeurs à un objet SharedObject :

public var currentUserName:String = "Reiner"; 
public var itemsArray:Array = new Array(101,346,483); 
public var currentUserIsAdmin:Boolean = true; 
mySO.data.userName = currentUserName; 
mySO.data.itemNumbers = itemsArray; 
mySO.data.adminPrivileges = currentUserIsAdmin;

Après avoir affecté des valeurs à la propriété data , vous devez demander à Flash Player les écrire dans le fichier SharedObject. Pour forcer Flash Player à écrire les valeurs dans le fichier SharedObject, utilisez la méthode SharedObject . flush() , comme suit :

mySO.flush();

Si vous n’appelez pas la méthode SharedObject.flush() , Flash Player écrit les valeurs dans le fichier à la fermeture de l’application. Cependant, cette méthode ne permet pas à l’utilisateur d’augmenter l’espace disponible nécessaire à Flash Player pour enregistrer les données si la taille de ces dernières est supérieure aux paramètres par défaut. La meilleure pratique consiste donc à appeler SharedObject.flush() .

Si vous utilisez la méthode flush() pour écrire des objets partagés sur le disque dur de l’ordinateur, vous devez vérifier avec soin si l’utilisateur a explicitement désactivé le stockage local à l’aide du Gestionnaire de paramètres de Flash Player ( www.macromedia.com/support/documentation/fr/flashplayer/help/settings_manager07.html ), comme illustré dans cet exemple :

var so:SharedObject = SharedObject.getLocal("test"); 
trace("Current SharedObject size is " + so.size + " bytes."); 
so.flush();

Stockage d’objets dans les objets partagés

Vous pouvez stocker des objets simples comme Arrays ou Strings dans la propriété data de l’objet SharedObject.

L’exemple suivant est une class ActionScript qui définit des méthodes contrôlant l’interaction avec l’objet partagé. Ces méthodes permettent à l’utilisateur d’ajouter et de supprimer des objets de l’objet partagé. Cette classe stocke une collection ArrayCollection qui contient des objets simples.

package { 
    import mx.collections.ArrayCollection; 
    import flash.net.SharedObject; 
 
    public class LSOHandler { 
 
        private var mySO:SharedObject; 
        private var ac:ArrayCollection; 
        private var lsoType:String; 
 
        // The parameter is "feeds" or "sites". 
        public function LSOHandler(s:String) { 
            init(s); 
        } 
 
        private function init(s:String):void { 
            ac = new ArrayCollection(); 
            lsoType = s; 
            mySO = SharedObject.getLocal(lsoType); 
            if (getObjects()) { 
                ac = getObjects(); 
            } 
        } 
 
        public function getObjects():ArrayCollection { 
            return mySO.data[lsoType]; 
        } 
 
        public function addObject(o:Object):void { 
            ac.addItem(o); 
            updateSharedObjects(); 
        } 
 
        private function updateSharedObjects():void { 
            mySO.data[lsoType] = ac; 
            mySO.flush(); 
        } 
    } 
 
}

L’application Flex suivante crée une occurrence de la classe ActionScript pour chacun des types d’objets partagés dont elle a besoin. Elle appelle ensuite des méthodes sur cette classe lorsque l’utilisateur ajoute ou supprime des blogs ou des URL de site.

<?xml version="1.0"?> 
<!-- lsos/BlogAggregator.mxml --> 
<mx:Application 
    xmlns:local="*" 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    creationComplete="initApp()" 
    backgroundColor="#ffffff" 
> 
    <mx:Script> 
        <![CDATA[ 
        import mx.collections.ArrayCollection; 
        import mx.utils.ObjectUtil; 
        import flash.net.SharedObject; 
 
        [Bindable] 
        public var welcomeMessage:String; 
        
        [Bindable] 
        public var localFeeds:ArrayCollection = new ArrayCollection(); 
 
        [Bindable] 
        public var localSites:ArrayCollection = new ArrayCollection(); 
 
        public var lsofeeds:LSOHandler; 
        public var lsosites:LSOHandler; 
 
        private function initApp():void { 
            lsofeeds = new LSOHandler("feeds"); 
            lsosites = new LSOHandler("sites"); 
            
            if (lsofeeds.getObjects()) { 
                localFeeds = lsofeeds.getObjects(); 
            } 
            if (lsosites.getObjects()) { 
                localSites = lsosites.getObjects(); 
            } 
        } 
        
        // Adds a new feed to the feeds DataGrid. 
        private function addFeed():void { 
            // Construct an object you want to store in the 
            // LSO. This object can contain any number of fields. 
            var o:Object = {name:ti1.text, url:ti2.text, date:new Date()}; 
            lsofeeds.addObject(o); 
    
            // Because the DataGrid's dataProvider property is 
            // bound to the ArrayCollection, Flex updates the 
            // DataGrid when you call this method. 
            localFeeds = lsofeeds.getObjects(); 
            
            // Clear the text fields. 
            ti1.text = '';        
            ti2.text = ''; 
        } 
        
        // Removes feeds from the feeds DataGrid. 
        private function removeFeed():void { 
            // Use a method of ArrayCollection to remove a feed. 
            // Because the DataGrid's dataProvider property is 
            // bound to the ArrayCollection, Flex updates the 
            // DataGrid when you call this method. You do not need 
            // to update it manually. 
            if (myFeedsGrid.selectedIndex > -1) { 
            
localFeeds.removeItemAt(myFeedsGrid.selectedIndex); 
             } 
        } 
        
        private function addSite():void { 
            var o:Object = {name:ti3.text, date:new Date()}; 
            lsosites.addObject(o); 
            localSites = lsosites.getObjects(); 
            ti3.text = '';                
        } 
        
        private function removeSite():void { 
            if (mySitesGrid.selectedIndex > -1) { 
            
localSites.removeItemAt(mySitesGrid.selectedIndex); 
            }       
        } 
 
        ]]> 
    </mx:Script> 
        
    <mx:Label text="Blog aggregator" fontSize="28"/> 
    
    <mx:Panel title="Blogs"> 
        <mx:Form id="blogForm"> 
            <mx:HBox> 
                <mx:FormItem label="Name:"> 
                    <mx:TextInput id="ti1" width="100"/> 
                </mx:FormItem> 
                <mx:FormItem label="Location:"> 
                    <mx:TextInput id="ti2" width="300"/> 
                </mx:FormItem> 
                <mx:Button id="b1" label="Add Feed" click="addFeed()"/> 
            </mx:HBox> 
 
            <mx:FormItem label="Existing Feeds:"> 
                <mx:DataGrid 
                    id="myFeedsGrid" 
                    dataProvider="{localFeeds}" 
                    width="400" 
                /> 
            </mx:FormItem> 
            <mx:Button id="b2" label="Remove Feed" click="removeFeed()"/> 
        </mx:Form> 
    </mx:Panel> 
    
    <mx:Panel title="Sites"> 
        <mx:Form id="siteForm"> 
            <mx:HBox> 
                <mx:FormItem label="Site:"> 
                    <mx:TextInput id="ti3" width="400"/> 
                </mx:FormItem> 
                <mx:Button id="b3" label="Add Site" click="addSite()"/> 
            </mx:HBox> 
 
            <mx:FormItem label="Existing Sites:"> 
                <mx:DataGrid 
                    id="mySitesGrid" 
                    dataProvider="{localSites}" 
                    width="400" 
                /> 
            </mx:FormItem> 
            <mx:Button id="b4" label="Remove Site" click="removeSite()"/> 
        </mx:Form> 
    </mx:Panel> 
    
</mx:Application>

Stockage des objets typés dans les objets partagés

Vous pouvez stocker des occurrences ActionScript typées dans des objets partagés. Pour ce faire, il vous suffit d’appeler la méthode flash.net.registerClassAlias() pour enregistrer la classe. Si vous créez une occurrence de votre classe et que vous la stockez dans les données membres de votre objet partagé, puis que vous lisez ce dernier, vous obtenez une occurrence typée. Par défaut, la propriété objectEncoding de l’objet SharedObject prend en charge le codage AMF3 et décompresse votre occurrence stockée à partir de l’objet SharedObject ; l’occurrence stockée conserve le même type spécifié lorsque vous avez appelé la méthode registerClassAlias() .

(iOS uniquement) Empêcher la sauvegarde sur le cloud des objets partagés locaux

Vous pouvez définir la propriété SharedObject.preventBackup de manière à contrôler si les objets locaux partagés sont sauvegardés sur le service iOS de sauvegarde sur le cloud. Apple demande de procéder de cette manière pour tout contenu qu’il est possible de générer ou télécharger à nouveau, mais qui est nécessaire au bon fonctionnement de votre application lors d’une utilisation hors ligne.

Création de plusieurs objets partagés

Vous pouvez créer plusieurs objets partagés pour la même application Flex. Pour ce faire, affectez à chacun d’entre eux un nom d’occurrence différent, comme indiqué dans l’exemple suivant :

public var mySO:SharedObject = SharedObject.getLocal("preferences"); 
public var mySO2:SharedObject = SharedObject.getLocal("history");

Cette action entraîne la création des fichiers preferences.sol et history.sol file dans le répertoire local de l’application Flex.

Création d’un SharedObject sécurisé

Lorsque vous créez un SharedObject local ou distant à l’aide de getLocal() ou getRemote() , un paramètre facultatif nommé secure détermine si l’accès à l’objet partagé se limite aux fichiers SWF diffusés via une connexion HTTPS. Si ce paramètre a la valeur true et que votre fichier SWF est diffusé sur HTTPS, Flash Player crée un nouvel objet sécurisé ou obtient une référence à un objet partagé sécurisé existant. Cet objet partagé sécurisé peut uniquement être lu ou écrit par des fichiers SWF reçus via des connexions HTTPS appelant SharedObject.getLocal() avec le paramètre secure réglé sur true . Si ce paramètre a la valeur false et que votre fichier SWF est diffusé sur HTTPS, Flash Player crée un nouvel objet partagé ou obtient une référence à un objet partagé existant.

Cet objet partagé peut être lu ou écrit par des fichiers SWF reçus via des connexions autres que HTTPS. Si votre fichier SWF est diffusé via une connexion autre que HTTPS et que vous essayez de régler ce paramètre sur true , la création d’un objet partagé (ou l’accès à un objet partagé sécurisé précédemment créé) échoue, une erreur est renvoyée et l’objet partagé devient null . Si vous tentez d’exécuter l’extrait de code suivant à partir d’un connexion non HTTPS, la méthode SharedObject.getLocal() renvoie une erreur :

try 
{ 
    var so:SharedObject = SharedObject.getLocal("contactManager", null, true); 
} 
catch (error:Error) 
{ 
    trace("Unable to create SharedObject."); 
}

Quelle que soit la valeur de ce paramètre, les objets partagés créés sont comptabilisés dans la quantité d’espace disque total autorisée pour un domaine.

Affichage du contenu d’un objet partagé

Des valeurs sont stockées dans un objet partagé, au sein de la propriété data . Vous pouvez passer en boucle chaque valeur d’une occurrence d’objet partagé à l’aide de la boucle for..in , comme le montre l’exemple suivant :

var so:SharedObject = SharedObject.getLocal("test"); 
so.data.hello = "world"; 
so.data.foo = "bar"; 
so.data.timezone = new Date().timezoneOffset; 
for (var i:String in so.data) 
{ 
    trace(i + ":\t" + so.data[i]); 
}

Destruction d’objets partagés

Pour détruire un objet SharedObject sur le client, faites appel à la méthode SharedObject.clear() . Cette action ne détruit pas les répertoires du chemin par défaut pour les objets partagés de l’application.

L’exemple suivant supprime le fichier SharedObject du client :

public function destroySharedObject():void { 
    mySO.clear(); 
}

Exemple SharedObject

L’exemple suivant illustre le stockage d’objets simples, tel un objet Date, dans un objet SharedObject sans avoir à sérialiser et désérialiser manuellement ces objets.

L’exemple suivant commence par un souhait de bienvenue en tant que nouveau visiteur. Lorsque vous cliquez sur Déconnexion, l’application stocke la date actuelle dans un objet partagé. La prochaine fois que vous lancez cette application ou que vous actualisez la page, l’application vous souhaite la bienvenue avec un rappel de l’heure à laquelle vous vous êtes déconnecté.

Pour voir l’application en action, lancez-la, cliquez sur Déconnexion, puis réactualisez la page. L’application affiche la date et l’heure auxquelles vous avez cliqué sur le bouton Déconnexion lors de votre précédente visite. Vous pouvez supprimer à tout moment les informations stockées en cliquant sur le bouton Supprimer le LSO.

<?xml version="1.0"?> 
<!-- lsos/WelcomeMessage.mxml --> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initApp()"> 
  <mx:Script><![CDATA[ 
  public var mySO:SharedObject; 
  [Bindable] 
  public var welcomeMessage:String; 
 
  public function initApp():void { 
     mySO = SharedObject.getLocal("mydata"); 
     if (mySO.data.visitDate==null) { 
        welcomeMessage = "Hello first-timer!" 
     } else { 
        welcomeMessage = "Welcome back. You last visited on " + 
           getVisitDate(); 
     } 
  } 
 
  private function getVisitDate():Date { 
     return mySO.data.visitDate; 
  } 
 
  private function storeDate():void { 
     mySO.data.visitDate = new Date(); 
     mySO.flush(); 
  } 
  
  private function deleteLSO():void { 
     // Deletes the SharedObject from the client machine. 
     // Next time they log in, they will be a 'first-timer'. 
     mySO.clear(); 
  } 
  
  ]]></mx:Script> 
  <mx:Label id="label1" text="{welcomeMessage}"/> 
  <mx:Button label="Log Out" click="storeDate()"/> 
  <mx:Button label="Delete LSO" click="deleteLSO()"/> 
</mx:Application>