views:

87

answers:

2

Hey, I'm having trouble doing a file upload with FileReference.

The upload works ok when running the swf in standalone. It works sending the file to a remote server and to localhost (running the same app). But when the swf is embeded in firefox, chrome or safari, I get the IOError #2038. The strange thing is that it works ok with IE8... I've also tried uploading the file from an html form and it works (on every browser). A crossdomain.xml is set in place with full access but it never gets called (it shouldn't anyways...)

Any help is much appreciated!

A: 

FileReference is, let's say, rather odd on how it works with relative paths. In most cases, the base path is the path your swf was loaded from. Except for IE (or it was the other way round? I can't remember right now). I think this is not an IE/Firefox/chrmoe issue, but rather a player issue. There's a flash player for IE -that uses ActiveX- and a player for the rest of the browsers. At some point they diverge in how they handle relative paths for FileReference objects. If this is a feature, it's quite stupid, so my feeling is this is a bug, but haven't checked the bug base, so I'm not sure if it's officially considered a bug or not. Also, setting the base_path in the embed code doesn't work.

Anyway, the only sane way to avoid this madness is using a full path. Trying to detect if it's IE or not will probably work, but I think at some point this annoyance will be fixed; and when that happens, your code will break, so I think it's a bad idea.

Now, you'll probably not want to hardcode the full path in your swf, so a simple solution I've used to work around this (assuming you can change the embed code) is passing this path through a flash var when you embed your swf. Generally, I retrieve this path with php so I don't have to manually change it when deploying or if you move stuff around (I pass the absolut path to the "app root", which for me it's usually the html code that embeds the swf; then I concatenate that to the relative path where the file that handles the post lives, so from your swf it's like using a relative path in a way).

So, if you can use some server side, you can just write this little piece of code once and forget about it. But even if you do this manually, it'll be easier to mantain than recompiling your swf.

Juan Pablo Califano
A: 

I've finally managed to solve this issue.

The problem arised because the user had to log in before performing the upload operation. When performing an upload operation with the FileReference object, flashplayer doesn't send the session cookie stored by the browser, it has something like it's own cookie space. You can google about the "Flash Cookie Bug" for more info.

The bug is already reported to Adobe:

  • bugs.adobe.com/jira/browse/FP-1044
  • bugs.adobe.com/jira/browse/FP-419
  • bugs.adobe.com/jira/browse/FP-201
  • bugs.adobe.com/jira/browse/FP-78

Can't post the links because of my rep (append https://)...

The solution I've implemented (pretty much the same way SWFUpload library solves this issue) is to manually send my sessionid when performing the upload.

I've found this link very usefull since I'm using a Django backend. http://blog.fogtunes.com/2009/11/howto-integrate-swfupload-with-django/

The idea is that the backend sends to the flash app the sessionid after performing the login. Then, when the flash app calls the upload() method, you should send this sessionid (adding it in the URLRequest data property inside an URLVariables object). Finally, when the request is received by the server it should use the sessionid to correctly set the active session before handling the upload operation.

var urlReq:URLRequest = new URLRequest("http://url-for-upload/");
urlReq.method = URLRequestMethod.POST;
urlReq.data = new URLVariables();
urlReq.data.sessionid = sessionid_from_server; // this is a variable holding the sessionid received by the server after performing the login
fileReference.upload(urlReq);
honi