Obiekty udostępnione

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Obiekt współużytkowany, czasami określany jako „plik cookie Flash”, to plik danych, który może zostać utworzony w komputerze przez odwiedzane serwery. Obiekty udostępnione są najczęściej używane w celu ułatwienia przeglądania Internetu. Umożliwiają na przykład personalizowanie wyglądu i działania najczęściej odwiedzanych stron internetowych.

Informacje o obiektach udostępnionych

Obiekty współużytkowane pod względem działania przypominają pliki cookie przeglądarki. Klasa SharedObject umożliwia zapisywanie danych na lokalnym dysku twardym użytkownika i odwoływanie się do tych danych w tej samej sesji lub w późniejszych sesjach. Aplikacje mają dostęp wyłącznie do swoich własnych danych w obiektach SharedObject i tylko wtedy, gdy działają w tej samej domenie. Dane nie są przesyłane na serwer i nie są dostępne dla innych aplikacji działających w innych domenach, mogą być jednak udostępniane aplikacjom z tej samej domeny.

Porównanie obiektów udostępnionych i plików cookie

Obiekty współużytkowane są bardzo podobne do plików cookie. Ponieważ większość programistów aplikacji internetowych wie, jak działają pliki cookie, celowe może być porównanie plików cookie z lokalnymi obiektami SharedObject.

Pliki cookie zgodne ze standardem RFC 2109 mają następujące cechy:

  • Ich termin ważności jest ograniczony i często domyślnie tracą ważność wraz z końcem sesji.

  • Pliki cookie z konkretnej witryny mogą być wyłączane przez klienta.

  • Obowiązuje limit liczby plików cookie: łącznie nie więcej niż 300 i nie więcej niż 20 z jednej witryny.

  • Wielkość pojedynczego pliku cookie jest zwykle ograniczona do 4 KB.

  • Niekiedy pliki cookie są postrzegane jako zagrożenie, dlatego niekiedy zostają wyłączone w systemie klienckim.

  • Są przechowywane w położeniu określonym przez przeglądarkę kliencką.

  • Są przesyłane z klienta na serwer za pośrednictwem protokołu HTTP.

    Natomiast obiekty współużytkowane mają następujące właściwości:

  • Domyślnie nie tracą ważności.

  • Domyślnie wielkość każdego obiektu jest ograniczona do 100 KB.

  • Można w nich przechowywać proste typy danych (takie jak String, Array i Date).

  • Są przechowywane w położeniu określonym przez aplikację (w katalogu głównym użytkownika).

  • Nigdy nie są przesyłane między klientem a serwerem.

Informacje o klasie SharedObject

Korzystając z klasy SharedObject , można tworzyć i usuwać obiekty współużytkowane oraz sprawdzić, jaką objętość ma obecnie używany obiekt SharedObject.

Tworzenie obiektu współużytkowanego

Aby utworzyć obiekt SharedObject , należy użyć metody SharedObject.getLocal() , której składnia jest następująca:

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

W poniższym przykładzie tworzony jest obiekt współużytkowany o nazwie mySO:

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

Powoduje to utworzenie na komputerze klienta pliku o nazwie preferences.sol.

Określenie lokalny oznacza położenie obiektu współużytkowanego. W tym przypadku odtwarzacz Adobe® Flash® Player zapisze plik obiektu SharedObject lokalnie w katalogu głównym użytkownika.

Gdy tworzony jest obiekt współużytkowany, program Flash Player tworzy nowy katalog dla aplikacji i domeny wewnątrz obszaru izolowanego. Tworzy również plik *.sol, w którym przechowywane są dane obiektu SharedObject. Domyślne położenie tego pliku to podkatalog w katalogu głównym użytkownika. W poniższej tabeli przedstawiono domyślne położenia tego katalogu:

System operacyjny

Położenie

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

Poniżej katalogu #SharedObjects znajduje się katalog o losowej nazwie. Poniżej znajduje się katalog o nazwie zgodnej z nazwą hosta, następnie ścieżka do aplikacji, a na końcu plik *.sol.

Na przykład, jeśli w systemie Windows XP wywołano aplikację o nazwie MyApp.swf na hoście lokalnym w podkatalogu o nazwie /sos, program Flash Player zapisze plik *.sol w następującym położeniu:

c:/Documents and Settings/fred/Application Data/Macromedia/Flash Player/#SharedObjects/KROKWXRK/#localhost/sos/MyApp.swf/data.sol
Uwaga: Jeśli w wywołaniu metody SharedObject.getLocal() nie zostanie podana nazwa, program Flash Player nada plikowi nazwę undefined.sol.

Domyślnie program Flash może zapisywać lokalnie trwałe obiekty SharedObject o wielkości maksymalnie 100 KB na jedną domenę. Użytkownik może skonfigurować tę wartość. Gdy aplikacja próbuje zapisać w obiekcie współużytkowanym dane, które spowodowałyby przekroczenie limitu 100 KB, w programie Flash Player wyświetlane jest okno dialogowe, w którym użytkownik może zezwolić na powiększenie magazynu lokalnego dla domeny, która tego zażądała, lub odmówić powiększenia magazynu lokalnego.

Określanie ścieżki

Opcjonalny parametr pathname umożliwia określenie położenia pliku obiektu SharedObject . Położenie to musi być podkatalogiem katalogu SharedObject danej domeny. Na przykład, w wypadku wywołania aplikacji na hoście localhost i określeniu ścieżki:

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

program Flash Player zapisze plik obiektu SharedObject w katalogu /#localhost (lub /localhost, jeśli aplikacja działa w trybie offline). Takie rozwiązanie jest przydatne, jeśli chcemy, by więcej niż jedna aplikacja na kliencie miała dostęp do tego samego obiektu współużytkowanego. W tym przypadku na kliencie mogłyby działać dwie aplikacje Flex i w obu tych aplikacjach można byłoby określić ścieżkę do obiektu współużytkowanego wskazującą na katalog główny domeny; klient miałby dostęp do tego samego obiektu współużytkowanego z obu aplikacji. Aby współużytkować dane między aplikacjami bez tworzenia obiektów trwałych, można użyć obiektu LocalConnection.

W razie określenia nieistniejącego katalogu, program Flash Player nie utworzy pliku obiektu SharedObject.

Dodawanie danych do obiektu współużytkowanego

Do dodawania danych do pliku *.sol obiektu SharedObject służy właściwość data tego obiektu. Aby dodać nowe dane do obiektu współużytkowanego, należy użyć następującej składni:

sharedObject_name.data.variable = value;

Poniższy przykład ilustruje dodawanie do obiektu SharedObject właściwości userName , itemNumbers i adminPrivileges oraz ich wartości:

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;

Po przypisaniu wartości do właściwości data należy nakazać programowi Flash Player zapisanie tych wartości w pliku obiektu SharedObject. Aby wymusić na programie Flash Player zapisanie wartości w pliku obiektu SharedObject, należy użyć metody SharedObject . flush() , tak jak przedstawiono to poniżej:

mySO.flush();

Jeśli metoda SharedObject.flush() nie zostanie wywołana, program Flash Player zapisze wartości do pliku z chwilą zakończenia pracy aplikacji. Jednak wówczas użytkownik nie będzie miał możliwości powiększenia magazynu przeznaczonego na przechowywanie danych programu Flash Player, jeśli wielkość danych przekroczy domyślny limit. Dlatego dobrą praktyką jest wywoływanie metody SharedObject.flush() .

Jeśli do zapisywania obiektów udostępnionych na dysku twardym używana jest metoda flush() , należy sprawdzić, czy użytkownik jawnie wyłączył magazyn lokalny za pomocą Menedżera ustawień programu Flash Player ( www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html ), co przedstawia poniższy przykład.

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

Przechowywanie obiektów w obiektach współużytkowanych

We właściwości data obiektu SharedObject można zapisywać obiekty należące do typów prostych, takich jak Array i String.

W poniższym przykładzie przedstawiono klasę języka ActionScript, która definiuje metody sterujące interakcją z obiektem współużytkowanym. Metody te umożliwiają użytkownikowi dodawanie i usuwanie obiektów z obiektu współużytkowanego. W klasie tej zapisana jest kolekcja ArrayCollection zawierająca obiekty proste.

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(); 
        } 
    } 
 
}

Poniższa aplikacja Flex tworzy instancję klasy ActionScript dla każdego typu obiektów współużytkowanych, jakiego potrzebuje. Następnie wywołuje metody tej klasy, gdy użytkownik dodaje lub usuwa blogi lub adresy URL witryn.

<?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>

Przechowywanie obiektów o określonym typie w obiektach współużytkowanych

W obiektach współużytkowanych można przechowywać instancje określonych typów języka ActionScript. Należy w tym celu wywołać metodę flash.net.registerClassAlias() w celu zarejestrowania klasy. Gdy utworzona zostanie instancja klasy, która zostanie następnie zapisana w elemencie danych obiektu współużytkowanego, to w wyniku odczytania instancji z obiektu zwrócona zostanie instancja o określonym typie. Domyślnie właściwość objectEncoding obiektu SharedObject obsługuje kodowanie AMF3 i rozpakowuje zapisaną instancję z obiektu SharedObject; zapisana instancja zachowuje typ określony w wywołaniu metody registerClassAlias() .

(Tylko iOS) Zapobieganie wykonywaniu kopii zapasowych lokalnych obiektów współużytkowanych w środowisku rozproszonym

Ustawiając właściwość SharedObject.preventBackup , można określić, czy lokalne obiekty współużytkowane mają być uwzględniane przy tworzeniu kopii zapasowych w usłudze systemu iOS opartej na środowisku rozproszonym. Firma Apple wymaga stosowania tej opcji w przypadku zawartości możliwej do ponownego wygenerowania lub pobrania. Nie jest to konieczne do właściwego działania aplikacji podczas jej używania offline.

Tworzenie wielu obiektów współużytkowanych

Istnieje możliwość utworzenia wielu obiektów współużytkowanych dla tej samej aplikacji Flex. W tym celu należy przypisać każdej z nich inną nazwę instancji, co ilustruje poniższy przykład:

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

W rezultacie w katalogu lokalnym aplikacji Flex utworzone zostaną pliki preferences.sol i history.sol.

Tworzenie bezpiecznego obiektu SharedObject

Po utworzeniu lokalnego lub zdalnego obiektu SharedObject za pomocą metody getLocal() lub getRemote() dostępny jest opcjonalny parametr o nazwie secure , który określa, czy dostęp do obiektu współużytkowanego jest ograniczony do plików SWF, które są wprowadzane przez połączenie HTTPS. Jeśli ten parametr ma wartość true , a plik SWF został wprowadzony przez HTTPS, wówczas program Flash Player tworzy nowy obiekt współużytkowany lub pobiera odwołanie do istniejącego bezpiecznego obiektu współużytkowanego. Odczytywać z lub zapisywać do tego bezpiecznego obiektu udostępnionego mogą tylko pliki SWF dostarczone za pomocą protokołu HTTPS, które wywołują metodę SharedObject.getLocal() z parametrem secure ustawionym na true . Jeśli dla tego parametru ustawiona jest wartość false , a plik SWF został dostarczony za pomocą HTTPS, program Flash Player tworzy nowy obiekt współużytkowany lub pobiera odwołanie do istniejącego obiektu współużytkowanego.

Ten obiekt współużytkowany może być odczytywany/zapisywany przez pliki SWF dostarczone przez połączenia inne niż HTTPS. Jeśli plik SWF został dostarczony przez połączenie inne niż HTTPS, a użytkownik podejmie próbę ustawienia dla tego parametru wartości true , wówczas utworzenie nowego obiektu współużytkowanego (lub dostęp do poprzednio utworzonego bezpiecznego obiektu współużytkowanego) nie powiedzie się, wystąpi błąd, a dla obiektu współużytkowanego zostanie ustawiona wartość null . Jeśli użytkownik podejmie próbę uruchomienia poniższego urywka z połączenia innego niż HTTPS, metoda SharedObject.getLocal() zwróci błąd:

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

Niezależnie od wartości tego parametru tworzone obiekty udostępnione są wliczane do całkowitej ilości miejsca na dysku dostępnej dla domeny.

Wyświetlanie zawartości obiektu udostępnionego

Wartości są zapisywane w obiektach współużytkowanych we właściwości data . Dla każdej wartości można wykonać pętlę w instancji obiektu współużytkowanego, korzystając z pętli for..in , jak w poniższym przykładzie:

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]); 
}

Niszczenie obiektów udostępnionych

Aby zlikwidować obiekt SharedObject na kliencie, należy użyć metody SharedObject.clear() . Nie powoduje to usunięcia katalogów w domyślnej ścieżce obiektów współużytkowanych aplikacji.

Poniższy przykład ilustruje usuwanie pliku obiektu SharedObject z klienta:

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

Przykład użycia klasy SharedObject

Poniższy przykład ilustruje sposób zapisywania prostych obiektów, takich jak obiekt Date, w obiekcie SharedObject bez konieczności ręcznej serializacji i deserializacji tych obiektów.

Działanie poniższego przykładu rozpoczyna się od powitania użytkownika jako osoby po raz pierwszy korzystającej z aplikacji. Po kliknięciu przycisku Log Out aplikacja zapisuje bieżącą datę w obiekcie współużytkowanym. Po następnym uruchomieniu aplikacji lub odświeżeniu strony aplikacja wita użytkownika informacją o tym, kiedy ostatnio się wylogował.

Aby zobaczyć aplikację w działaniu, należy ją uruchomić, kliknąć przycisk Log Out, a następnie odświeżyć stronę. Aplikacja wyświetli datę i godzinę kliknięcia przycisku Log Out podczas ostatniej wizyty. Zapisane informacje można w dowolnej chwili usunąć, klikając przycisk Delete 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>