Flex 3 Close UrlLoader создает исключение
Я пытаюсь смоделировать метод "HEAD" с помощью UrlLoader; по сути, я просто хочу проверить наличие файла без загрузки всего файла. Я подумал, что просто использовал бы HttpStatusEvent, но следующий код выдает исключение (которое я не могу обернуть в блок try/catch), когда вы работаете в режиме отладки.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()">
<mx:Script>
<![CDATA[
private static const BIG_FILE:String = "http://www.archive.org/download/gspmovvideotestIMG0021mov/IMG_0021.mov";
private var _loader:URLLoader;
private function init():void {
_loader = new URLLoader();
_loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler);
_loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
_loader.load(new URLRequest(BIG_FILE));
}
public function unload():void {
try {
_loader.close();
_loader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler);
_loader.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
}
catch(error:Error) {
status.text = error.message;
}
}
private function errorHandler(event:Event):void {
status.text = "error";
unload();
}
private function statusHandler(event:HTTPStatusEvent):void {
if(event.status.toString().match(/^2/)) {
status.text = "success";
unload();
}
else {
errorHandler(event);
}
}
]]>
</mx:Script>
<mx:Label id="status" />
Вместо этого я попытался использовать ProgressEvents, но кажется, что около 404 страниц возвращают контент, поэтому событие состояния будет правильно определять, существует ли страница.
У кого-нибудь есть идеи?
2 ответа
Это ошибка в классе URLLoader, я думаю.
Если вы прочитаете сообщение об ошибке (по крайней мере, то, которое я получил, вы не вставили yorrs!), Вы увидите это:
Ошибка: Ошибка № 2029: у этого объекта URLStream нет потока, открытого в flash.net::URLStream/readBytes() в flash.net::URLLoader/onComplete()
Это дает вам некоторое представление о том, что происходит. Класс URLLoader внутренне использует объект URLStream, который обеспечивает низкоуровневый доступ к загруженным данным.
Сообщение об ошибке указывает, что на URLLoader вызывается обработчик onComplete. Файл большой, но, вероятно, кешируется, поэтому загружается довольно быстро. Теперь, если вы добавите прослушиватель для событий хода выполнения и завершения, вы увидите порядок, в котором запускаются события:
- прогресс
- статус
- полный
Документы подтверждают это:
Обратите внимание, что событие httpStatus (если оно есть) отправляется до (и в дополнение к) любого события завершения или ошибки.
Теперь вы можете видеть, что проблема в том, что из обработчика состояния вы вызываете close(). Это закрывает поток. Но, по-видимому (и это ошибка, я думаю), обработчик onComplete в классе URLLoader не проверяет, открыт поток или нет. (Из Actionscript нет способа проверить это, так что вам придется заключить код в try/catch). Вы не можете читать данные из закрытого потока, поэтому он и дует.
Я вижу 2 способа это исправить:
1) Отложите выполнение функции, которая вызывает close() (ваш метод unload), поэтому close () вызывается после вызова внутреннего метода onComplete URLLoader.
То есть сделать это:
setTimeout(unload,1);
вместо этого:
unload();
2) Используйте URLStream вместо URLLoader. Первый вариант кажется мне хакерским обходным решением, поэтому я бы выбрал последний в вашей ситуации. Использование URLStream обычно означает больше работы на вашей стороне, но в этом случае вы на самом деле не заинтересованы в чтении каких-либо данных, поэтому это не имеет большого значения. Кроме того, вам нужно всего лишь изменить две строки в вашем текущем коде:
Вот этот:
private var _loader:URLStream;
И этот:
_loader = new URLStream();
И все готово.
Я столкнулся с подобной проблемой.
Проблема в том, что я обнаружил этот вызов:
_loader.close();
Ошибка произошла, когда я попытался закрыть файл, который я даже не открыл. Поэтому в предложении "try" проверьте, открыт ли файл, прежде чем пытаться его закрыть.
Майк