Why does the load method of the URLStream class dispatch Event.OPEN instead of IOErrorEvent.IO_ERROR when the SWF is on a webserver and when trying to load an invalid URL?
The same doesn't apply when running the SWF locally.
Sample code:
var CLS_UrlStream:URLStream = new URLStream(); // Initialize URLStream class instance.
CLS_UrlStream.addEventListener(Event.OPEN, FUN_StreamHandler); // Listen for successful connections.
CLS_UrlStream.addEventListener(IOErrorEvent.IO_ERROR, FUN_StreamHandler); // Listen for conenction errors.
CLS_UrlStream.load(new URLRequest("InvalidURL")); // Load file.
private function FUN_StreamHandler(FUN_PAR_Event:Event):void {
trace("EVENT TYPE: " + FUN_PAR_Event.type);
}
// Outputs: EVENT TYPE: open
Event.OPEN gets triggered on load. So will always be called.
You probably want HTTPStatusEvent.HTTP_STATUS
When the SWF is running on the server and is requesting for a resource that doesn't exist, the server actually sends an error message which counts as data, thus there is no error event. The same didn't apply locally because there was no web server to respond with an error when a request for an nonexistent file is made. Discovered this by tracing live with the Monster Debugger.
Related
I am running an embedded flash 'swf' inside a LAN network with a proxy server. Proxy server interrupts some urls and returns my usage information. I am trying to access this information by sending those urls. I can see this traffic in firebug ,But the URLLoader does not seem to read it. Neither Complete event or progress event get fired. I tried URLStream with a timer also,but availableBytes were always zero.Is it possible to read this information?
private var getLoader:URLLoader = new URLLoader();
private var sendRequest:URLRequest = new URLRequest();
public function XDomain() {
sendRequest= new URLRequest("requesturl");
getLoader.addEventListener(Event.COMPLETE, eventHandler);
getLoader.addEventListener(ProgressEvent.PROGRESS,eventHandler2);
getLoader.load(sendRequest);
}
private function eventHandler(event:Event):void {
trace("running");
}
private function eventHandler2(event:ProgressEvent):void {
trace("runninhg progresss");
}
Thanks in advance //
Edit: I had this security error
[SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048"]
"But the URLLoader does not seem to read it..."
Use URLStream (without a timer, cos what does that even achieve?) to reach the link and inside your related progressEvent use a readUTFBytes to get any text response data given by that link's server. Use progressEvent to also check size of any received bytes (the event fires multiple times, getting 64kb packets, until full data is downloaded).
about Error #2048:
URLloader is a decoder for visual data (jpg, png, swf, text) but for non-text data it expects a crossdomain.xml to exist at the other server you are accessing the swf from (both sides must also have a matching same http or https. Again best way to by-pass this is to just load the bytes into a byte array (via URLStream but the progressEvents now should write to your byte array) then later use URLLoader.loadBytes( yourSWFBytes );
i want to save the swf data in local so i can recreate it again and again.though most web browser has cache mechanism ,once a resource is downloaded,the application can get the resource from the local. but the browser still need to check the remote server's file's time stamp to make sure the remote file was not updated.that's make the process delay.
i want to handle it by myself ,so i save the downloaded data in the application.the trouble is i didn't find a way to recreate a new instance of the loaded swf immediately.for example,if i download a jpeg file,i finally got a bitmapdata , so i keep the bitmapdata,if i need a copy,i simply use clone() . but swf is different,i dont know how to clone the swf instance.
my way is load swf as binary array,and load it by Loader.loadBytes,here's my code.
public static function loadSWFByte(data:ByteArray,callback:Function,domain:ApplicationDomain):void{
var loader:Loader = new Loader();
var f:Function = function(e:Event):void{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,f);
if(callback!=null){
callback(loader.content,loader.contentLoaderInfo);
}
}
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,f);
loader.loadBytes(data,new LoaderContext(false,domain));
}
if i need to create it,i always use callback,thus make coding complicated.Is there a way i can get the instance without using callback?
Loading SWF bytes or from URL is always async , but You can load it once and clone each time:
// when loader load is complete
var cl:Class = loader.content["constructor"];
var clone:* = new cl();
My application requires that I am able to abort/close a URLLoader instance at any point in the post-connect stage; that is, regardless if I have connected and the file transfer has already begun, or whether I have connected, and the file transfer has yet to commence (the server has not begun sending the file yet).
Here is my code:
var myTextLoader:URLLoader = new URLLoader();
myTextLoader.load(new URLRequest("myText.txt"));
This is what I have noticed:
When I connect to a server, and the server starts sending the file immediately, DURING the actual file transfer, if I invoke myTextLoader.close(), it aborts immediately. This is expected. I can monitor this by executing the SWF in Firefox,and noticing that when I issue the close(), the network connecion goes from Pending to aborted.
However, if I connect to the server, and the file transfer has not actually begun yet (I have confirmed the connect event has fired, and the server has simply not begun sending the file), then myTextLoader.close() has no effect. Only AFTER the first bytes start being transferred from the server, will .close() have any effect. I can verify the connection is stuck in Pending in Firebug.. .close() has no effect until the transfer has started.
Any ideas how to work around this issue? I need to be able to invoke .close() and have the connection torn down regardless of the connection stage.
First thing I would think of, is create a bool "aborted" that is set to true where the close() method is invoked.
Like :
function abort():void {
_aborted = true;
myTextLoader.close();
}
Then check for its value anywhere in the onProgress event or any similar event, to actually call the URLLoader close() method again whenever its value is true...
function onProgress(evt:ProgressEvent):void {
if (_aborted) {
myTextLoader.close();
}
}
Its not a pretty thing and is an ugly workaround, but this could work, since when the first bits are actually received, you'll know if you already wanted to close it or not.
Did you find any bug report on that anywhere ?... I doubt it could be an intended behavior...
3rd party AS3 HTTPClient (https://github.com/gabriel/as3httpclient) appears to not exhibit this issue with close().
I have a site hosted at localhost:8000. Now, I have a server listening for websocket connections at localhost:8001. I would like my website to connect to this server through the websocket api like
var conn = new WebSocket('ws://localhost:8001');
But I get some errors in Chromium 6.0.472.62 upon calling
conn.send('something');
That looks like: Uncaught Error: INVALID_STATE_ERR: DOM Exception 11.
In Firefox 4 (4.0b8pre), I get the error:
An attempt was made to use an object that is not, or is no longer, usable" code: "11
I thought this was an issue with the handshake not supporting websocket draft76 on the server, but I am using http://github.com/miksago/node-websocket-server/tree/master/lib/ws/ which claims to support draft75 and draft76.
Also, the initial handshake seems to work fine. I can receive a response from the server upon creating the new WebSocket, however, the problems arise on the call to "send" from the client side.
Is this an issue with the same origin policy since my httpserver is on port 8000 and the websocket server is on 8001? If so, how can I work around this?
Perhaps you need to wait for the onopen event to fire?
var conn = new WebSocket('ws://localhost:8001');
conn.onopen = function (e) {
conn.send('something');
}
conn.onmessage = function (e) {
console.log('got something: ' + e.data);
}
Also, it's a good idea to hook the onclose and onerror events too.
I'm using URLLoader to POST to a server. The xml response from the server can respond with a 404 or a 403 (forbidden) error. However I am unable to get the response codes.
Here is the code
var urlString:String = "some url";
var urlRequest:URLRequest = new URLRequest(urlString);
var loader:URLLoader = new URLLoader();
loader.addEventListener( Event.COMPLETE, setXMLData );
loader.addEventListener( IOErrorEvent.IO_ERROR, ioHandler );
loader.addEventListener( HTTPStatusEvent.HTTP_STATUS, httpStatusHandler );
//...
public function httpStatusHandler(evt:HTTPStatusEvent):void {
trace("status is " + evt.status);
}
status is always 0 regardless whether i return 200, 400, 404, 301, 500, etc...
Any ideas?
For AIR Only you can use the httpResponseStatus. Otherwise in Flash/Flex without AIR you cannot.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/URLLoader.html#event:httpResponseStatus
httpResponseStatus Event
Event Object Type: flash.events.HTTPStatusEvent
HTTPStatusEvent.type property = flash.events.HTTPStatusEvent.HTTP_RESPONSE_STATUS
Language Version : ActionScript 3.0
Runtime Versions : AIR 1.0 AIR 1.0
Dispatched if a call to the load() method attempts to access data over HTTP, and Adobe AIR is able to detect and return the status code for the request.
Unlike the httpStatus event, the httpResponseStatus event is delivered before any response data. Also, the httpResponseStatus event includes values for the responseHeaders and responseURL properties (which are undefined for an httpStatus event. Note that the httpResponseStatus event (if any) will be sent before (and in addition to) any complete or error event.
the ability to look at the headers is limited in several browsers, therefore flash has a problem with being passed the information. this is mainly blamed on the browser settings, but i have yet to find one where it actually works. status event output.
i gave up and had the file print the response code in my projects, not wonderful (and somewhat defeating the point) but seems to work.
As a late answer (FWIW):
From what I've read, the status codes you get depend on what browser the Flash player is running in.
One article says you can only get 200 or 500. One SO question says they were getting 207 in Chrome but 0 in Firefox.
I, personally, have tested using the dev Flash player as well as an ActiveX version and was able to get many different 2XX/4XX HTTP status codes (but couldn't get the 3XX redirect codes I tried because the requests got redirected and returned 200s).