Общие объекты

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Общий объект, который иногда называется «Flash cookie», представляет собой файл с данными, который могут создавать на компьютере посещаемые сайты. Чаще всего общие объекты используются для улучшения просмотра Интернета. Например, они позволяют настроить внешний вид часто посещаемого веб-сайта.

Об общих объектах

Общие объекты функционируют подобно файлам cookie браузера. Класс SharedObject используется для хранения данных на локальном жестком диске пользователя и вызова этих данных во время того же или последующего сеанса. Приложения имеют доступ только к собственным данным SharedObject и только при их запуске на одном и том же домене. Данные не отправляются на сервер и недоступны для приложений, запускаемых на других доменах, однако доступны для приложений того же домена.

Сравнение общих объектов с файлами cookie

У файлов cookie и общих объектов существует много общего. Так как большинство веб-программистов знакомы с принципом работы файлов cookie, полезным будет сравнить файлы cookie с локальными объектами SharedObjects.

Как правило, файлы cookie, соответствующие стандарту RFC 2109, имеют следующие свойства:

  • срок действия, истекающий по умолчанию в конце сеанса;

  • возможность деактивирования клиентом на специфическом для сайта основании;

  • максимальное общее число файлов cookie, равное 300, но не более 20 файлов для одного сайта;

  • размер файла ограничен 4 Кб;

  • иногда расцениваются как угроза безопасности, в результате чего возможно их отключение на клиентском компьютере;

  • папка сохранения указывается браузером клиента;

  • передача от клиента на сервер происходит посредством HTTP.

    В отличие от файлов cookie, общие файлы имеют следующие свойства:

  • отсутствие срока действия по умолчанию;

  • размер файла по умолчанию ограничен 100 Кб;

  • возможность сохранения простых типов данных (например, String, Array и Date).

  • папка сохранения указывается приложением (в начальном каталоге пользователя);

  • передача от клиента на сервер отсутствует.

О классе SharedObject

При помощи класса SharedObject можно создавать и удалять общие объекты, а также определять текущий размер используемого объекта SharedObject.

Создание общих объектов

Для создания объекта SharedObject используется метод SharedObject.getLocal() со следующим синтаксисом:

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

В следующем примере описывается процесс создания общего объекта с именем mySO:

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

Таким образом на компьютере клиента создается файл с именем preferences.sol.

Понятие local указывает на местоположение общего объекта. В этом случае Adobe® Flash® Player сохраняет файл SharedObject в локальном начальном каталоге клиента.

При создании общего объекта Flash Player создает новый каталог для приложения и домена в изолированной среде. Также создается файл *.sol, хранящий данные SharedObject. Каталогом по умолчанию является подкаталог начального каталога пользователя. В следующей таблице представлены возможное расположение каталога по умолчанию:

Операционная система

Расположение

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

Под именем каталога #SharedObjects подразумевается каталог с произвольным именем. Далее следует каталог, имя которого идентично имени хоста, далее — путь к приложению и, наконец, файл *.sol.

Например, при запросе приложения с именем MyApp.swf, находящегося на локальном хосте в подкаталоге с именем /sos, Flash Player сохраняет файл *.sol по следующему пути (для Windows XP):

c:/Documents and Settings/fred/Application Data/Macromedia/Flash Player/#SharedObjects/KROKWXRK/#localhost/sos/MyApp.swf/data.sol
Примечание. Если имя в методе SharedObject.getLocal() не указано, Flash Player присваивает файлу имя undefined.sol.

По умолчанию Flash может локально сохранять постоянные объекты SharedObject размером до 100 Кб в каждом домене. Это значение может изменяться пользователем. При попытке сохранения приложением данных в общем объекте, увеличивающим его до размера более 100 Кб, Flash Player отображает диалоговое окно «Локальное сохранение», в котором пользователь может разрешить или запретить использование нескольких локальных хранилищ доменом, запращивающим доступ.

Определение пути

Существует возможность использования необязательного параметра pathname для указания местоположения файла SharedObject. Этот файл должен являться подкаталогом папки SharedObject данного домена. Например, при запросе приложения на локальном хосте и вводе следующей строки:

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

Flash Player записывает файл SharedObject в каталог /#localhost (или в каталог /localhost, если приложение является офлайн-приложением). Использование данной возможности наиболее оправдано при необходимости доступа нескольких приложений к одному и тому же общему объекту. В этом случае клиент может запустить два приложения Flex, в каждом из которых указан путь к общему объекту, находящемуся в корне домена; после этого клиент получит доступ из обоих приложений к одному и тому же общему объекту. Для совместного использования данных приложениями, не обеспечивающими неизменности данных, можно использовать объект LocalConnection.

При вводе несуществующего каталога Flash Player не создает файл SharedObject.

Добавление данных к общему объекту

В файл *.sol SharedObject можно добавлять данные, используя свойство data объекта SharedObject. Для добавления новых данных к общему объекту используйте следующий синтаксис:

sharedObject_name.data.variable = value;

В следующем примере выполняется добавление свойств userName, itemNumbers и adminPrivileges, а также их значений, к 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;

После присвоения значений свойству data Flash Player должен выполнить запись этих значений в файл SharedObject. Для инициирования записи значений в файл SharedObject используйте метод SharedObject.flush(), например:

mySO.flush();

Если пользователь не вызывает метод SharedObject.flush(), Flash Player записывает значения в файл при выходе из приложения. Однако такой способ не позволяет пользователю увеличивать доступное пространство, в котором Flash Player хранит данные, если они при записи превышают настройки по умолчанию. Поэтому рекомендуется вызывать метод SharedObject.flush().

При использовании метода flush() для записи общих объектов на жесткий диск пользователя следует соблюдать осторожность и проверять, не запретил ли пользователь локальное хранение с помощью менеджера параметров Flash Player Settings Manager (www.macromedia.com/support/documentation/ru/flashplayer/help/settings_manager07.html), как показано в следующем примере.

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

Сохранение объектов в общих объектах

Простые объекты, например, Arrays или Strings, могут сохраняться в свойстве SharedObject data.

В следующем примере представлен класс ActionScript, определяющий методы, которые управляют взаимодействием с общим объектом. Эти методы позволяют пользователю добавлять и удалять объекты из общих объектов. В данном классе хранится класс ArrayCollection, содержащий простые объекты.

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

Следующее приложение Flex создает экземпляр класса ActionScript для всех типов общих объектов, которым требуется экземпляр. После этого приложение вызывает методы данного класса при добавлении или удалении URL-адресов блогов или сайтов.

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

Сохранение объектов со строгим контролем типов в общих объектах

Существует возможность сохранения экземпляров ActionScript со строгим контролем типов в общих объектах. Данная возможность осуществляется посредством вызова метода flash.net.registerClassAlias() для регистрации класса. При создании экземпляра класса, сохранении его в элементе данных общего объекта и последующем выводе данных пользователь получит экземпляр со строгим контролем типов. По умолчанию свойство SharedObject objectEncoding поддерживает кодировку AMF3 и извлекает сохраненный экземпляр из объекта SharedObject. Сохраненный экземпляр сохраняет тот же тип, который был указан при вызове метода registerClassAlias().

(Только для iOS) Предотвращение резервоного копирования локальных общих объектов в облачное хранилище

Свойство SharedObject.preventBackup позволяет указывать, может ли производиться резервное копирование локальных общих объектов в облачное хранилище iOS. Таковы рекомендации Apple в отношении содержимого, которое можно восстановить или загрузить заново, но которое необходимо для правильной работы приложения в автономном режиме.

Создание нескольких общих объектов

Имеется возможность создания нескольких общих объектов для одного приложения Flex. Для этого каждому объекту требуется присвоить уникальное имя экземпляра, например:

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

Таким образом в локальном каталоге приложения Flex создаются файлы preferences.sol и history.sol.

Создание защищенного экземпляра SharedObject

Когда создается локальный или удаленный экземпляр SharedObject с помощью метода getLocal() или getRemote(), существует дополнительный параметр с именем secure, который определяет, разрешен ли доступ к общему объекту только для SWF-файлов, доставленных через HTTPS-соединение. Если данный параметр имеет значение true и SWF-файл доставляется через HTTPS, проигрыватель Flash Player создает новый защищенный общий объект или получает ссылку на существующий защищенный общий объект. Данный защищенный общий объект может считываться или записываться только теми SWF-файлами, доставленными по протоколу HTTPS, которые вызывают метод SharedObject.getLocal() с параметром secure, имеющим значение true. Если данный параметр имеет значение false и SWF-файл передается через HTTPS, проигрыватель Flash Player создает новый общий объект или получает ссылку на существующий общий объект.

Этот общий объект может считываться или записываться SWF-файлами, доставленными не через HTTPS-подключение. Если SWF-файл доставляется не через подключение HTTPS и вы пытаетесь установить для данного параметра значение true, то создание нового общего объекта (или доступ к ранее созданному защищенному общему объекту) завершится сбоем, будет выдано сообщение об ошибке, а общий объект получит значение null. Если вы попытаетесь выполнить следующий код не через подключение по протоколу HTTPS, метод SharedObject.getLocal() выдаст ошибку.

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

Независимо от значения данного параметра созданные общие объекты добавляются к общему объему дискового пространства, доступного для домена.

Отображение содержимого общего объекта

В общих объектах значения хранятся в свойстве data. Отобразить каждое значение в экземпляре SharedObject можно с помощью цикла for..in, как в следующем примере.

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

Удаление общих объектов

Для уничтожения SharedObject у клиента используйте метод SharedObject.clear(). Данный метод не удалит каталоги из пути, установленного по умолчанию для общих объектов приложения.

Пример иллюстрирует удаление файла SharedObject с клиентского компьютера:

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

Пример SharedObject

В следующем примере демонстрируется возможность хранения простых объектов, таких как объект Date, в объекте SharedObject SharedObject без ручной сериализации и десериализации этих объектов.

Следующий пример начинается с приветствия пользователя как посетителя, прошедшего первую регистрацию. При нажатии кнопки «Выход» приложение сохраняет текущую дату в общем объекте. При следующем запуске этого приложения или обновлении страницы на экран выводится приветствие с уведомлением о времени выхода из приложения.

Для того, чтобы увидеть приложение в действии, запустите приложение, нажмите кнопку «Выход», после чего обновите страницу. Приложение отобразит дату и время последнего нажатия кнопки «Выход». Сохраненную информацию можно удалить в любое время с помощью кнопки «Удалить локальный общий объект».

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