There is known issue in Internet Explorer (6,7) when Flex (HTTPService) is loading XML through SSL. Flash Player is throwing Error #2032: Stream Error in that case.
As advised by Microsoft and others, "Cache-Control: no-store" should be set on the server side to resolve the issue.
Unfortunately, I do not have access to application's backend, and thus I should solve it through Flex.
My goal is to load xml file with configurations at runtime.
Custom headers for GET requests are not allowed in Flex (let me know, if I am wrong). Thus I decided to accomplish my goal with POST request, and surprisingly it worked very well.
Here is the code I came with:
var httpService:HTTPService = new HTTPService();
httpService.url = 'config.xml';
httpService.method = 'POST';
httpService.requestTimeout = 10;
httpService.contentType = "application/xml";
httpService.headers["Cache-Control"] = "no-store";
httpService.resultFormat = "e4x";
var localResponder:Responder = new Responder(
function(event:ResultEvent):void {
//event.result returns the required xml configuration
},
function(event:FaultEvent):void {
});
var token:AsyncToken = httpService.send({});
token.addResponder(localResponder);
My question is: Could there be any side effects, when POST request is sent instead of GET request?
UPDATE:
To prove that GET-requests are stripped of headers, I've taken the code provided by #Reboog711 and created a little application. Here is the code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.rpc.http.HTTPService;
protected function sendHTTPRequest(event:MouseEvent):void
{
var httpService:HTTPService = new HTTPService();
httpService.url = 'xml.xml';
var headerData : Object = new Object();
headerData['Cache-Control'] = 'no-store';
httpService.headers = headerData;
httpService.send();
}
]]>
</fx:Script>
<s:Button label="SEND HTTP REQUEST"
horizontalCenter="0" verticalCenter="0" click="sendHTTPRequest(event)"/>
</s:Application>
And here is what I see in Charles application, when I send that HTTP-request.
You can test it yourself right here. Moreover, while I was trying to solve my problem, I've seen many evidences that GET-requests couldn't be sent with custom headers. You may take a look here.
Thanks!
You should be able to add headers to an HTTPService request without any problems. I have done it before, when integrating a Flex app with the YouTube APIs. Conceptually, it should be like this:
var httpService:HTTPService = new HTTPService();
var headerData : Object = new Object();
headerData['Cache-Control'] = 'no-store';
http.headers = headerData;
If you perform a Google Search other links come up. So long as your service supports both GET and POST requests; I do not know why you would experience any issues.
Related
I have an application compiled in Flex 4.5 and I load (with SWFLoader) other application compiled in Flex 3.5, it works fine but when I execute the sentence "SystemManager(myLoader.content)" the system shows the error:
TypeError: Error #1034: Error de conversión forzada: no se puede convertir _AnalizaOrganigramaTest_mx_managers_SystemManager#8450eb9 en mx.managers.SystemManager.
at AnaTestModule/_mlCargada()[C:\eanaliza\branch\peticiones3_p9184\40 flex\flex\AnaTestModule\src\AnaTestModule.mxml:28]
at AnaTestModule/__myLoader_complete()[C:\eanaliza\branch\peticiones3_p9184\40 flex\flex\AnaTestModule\src\AnaTestModule.mxml:43]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:13128]
at mx.controls::SWFLoader/http://www.adobe.com/2006/flex/mx/internal::contentLoaderInfo_completeEventHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\controls\SWFLoader.as:2292]
This is Flex 4.5 application code:
<fx:Script>
<![CDATA[
import mx.managers.SystemManager;
[Bindable]
public var loadedSM:SystemManager;
protected function _mlInit():void
{
myLoader.source = "/analiza_peticiones3_p9184/AnalizaOrganigramaTest-debug/AnalizaOrganigramaTest.swf";
myLoader.load();
}
private function _mlCargada():void
{
loadedSM = SystemManager(myLoader.content);
}
]]>
</fx:Script>
<s:SWFLoader id="myLoader"
loadForCompatibility="true"
complete="_mlCargada();"
maintainAspectRatio="true"
scaleContent="false"
/>
Can anyone help me?
Thanks in advance.
I've been working on something similar to this. Try using LoaderMax from GreenSock.
http://www.greensock.com/loadermax/
Im using a multiversioned sub application in mine and tried SystemManager as well, this lead to nowhere and I went back to LoaderMax. I was getting way too many RSL loading errors and whatnot using SystemManager.
you might also be running into the need for Marshalling support.
The parent App is SDK 4.5, this shares two SWC files (4.5) with another application (4.6)
The parent app loads an SDK 4.1 application into itself.
This is working for the most part, I am still trouble shooting linked assets and relative paths. But all in all, the application loads.
In the parent application view screen to load the child app:
[Bindable] private var childAppLink= "http://myserver.com/AppRoot/##version/controls/Application.swf";
[Bindable] private var altChildAppLink:String = "/AppRoot/##version/controls/Application.swf";
[Bindable] private var loaderQueue:LoaderMax = new LoaderMax({name:"ChildApp4_0_Loader",onProgress:handleLoaderProgress,onComplete:handleLoaderComplete,onError:handleLoadingError});
protected function loadUsingLoaderMax():void
{
childAppLink= StringUtils.replace(childAppLink,'##version',cm.s.childAppVersion);
altChildAppLink= StringUtils.replace(altChildAppLink,'##version',cm.s.childAppVersion);
var swfvars:SWFLoaderVars = new SWFLoaderVars();
var loaderRequest:URLRequest = new URLRequest();
var loaderVars:URLVariables = new URLVariables();
var loaderContexts:LoaderContext = new LoaderContext();
LoaderMax.contentDisplayClass = FlexContentDisplay;
loaderVars.DEBUG = cm.s.debug;
loaderVars.inChildMode = "true"; //set this as a string!
loaderVars.bpu = String(u.userId + ';' + u.currentLocationId);
loaderVars.sv = cm.s.childAppVersion;
loaderVars.KEYWORD = 'XXXXX';
loaderContexts.applicationDomain = new ApplicationDomain();
if(Security.sandboxType == Security.REMOTE)
loaderContexts.securityDomain = SecurityDomain.currentDomain;
loaderRequest.url = childAppLink;
loaderRequest.data = loaderVars;
loaderRequest.method = URLRequestMethod.GET;
swfvars.name("ChildApplication_4_0");
swfvars.estimatedBytes(410000000);
swfvars.container(ChildAppPH);
swfvars.x(0);
swfvars.autoPlay(true);
swfvars.scaleMode("none");
swfvars.alternateURL(altChildAppLink);
swfvars.context(loaderContexts);
loaderQueue.append(new com.greensock.loading.SWFLoader(loaderRequest,swfvars) );
this.addEventListener("mx.managers.SystemManager.isBootstrapRoot", systemManagerHandler);
this.addEventListener("mx.managers.SystemManager.isStageRoot", systemManagerHandler);
ShoplandPlaceholder.systemManager.addEventListener(FlexEvent.CREATION_COMPLETE,handleLoaderComplete);
loaderQueue.load();
ChildAppPH.visible = false;
ChildAppPH.alpha = 0;
}
protected function systemManagerHandler(event:Event):void
{
event.preventDefault();
}
and the MXML for the placeholder:
<s:SWFLoader id="ChildAppPH" width="1010" height="610" verticalCenter="305" horizontalCenter="505" top="10" />
The child application is setup to handle some new flashvars (this.parameters) which tell it what to do in its loading procedures. the child app is a standalone and can function without this, so it has now become a dual purpose application. 1) standalone, 2) child app (inChildMode)
Ive read a ton of online tutorials about this and cant seem to get a definite answer...
View1.mxml
navigator.pushView(views.view2, {response:"BLAH"});
View2.mxml
<fx:Script>
<![CDATA[
var result:String = // FIRST VIEW RESPONSE WHICH = BLAH
]]>
</fx:Script>
How is this done? Surely it should be simple? All the tutorials online seem very indepth!
Thanks
Phil
The property you are looking for is called data. It will get set AFTER construction. So, once data is set, you want to access data.response.
Got it
navigator.pushView(views.view2, "BLAH");
var result:String = String(data);
Duhhh
I have a Flex file upload script that uses URLRequest to upload files to a server. I want to add support for http authentication (password protected directories on the server), but I don't know how to implement this - I assume I need to extend the class somehow, but on how to I'm a little lost.
I tried to modify the following (replacing HTTPService with URLRequest), but that didn't work.
private function authAndSend(service:HTTPService):void{
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("someusername:somepassword");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.send();
}
I should point out that I'm not knowledgeable when it comes to ActionScript / Flex, although I have managed to successfully modify the upload script somewhat.
[Edit] - here is an update of my progress, based on the answer below, although I still cannot get this to work:
Thank you for your assistance. I've tried to implement your code but I've not had any luck.
The general behaviour I'm experiencing when dealing with HTTP authenticated locations is that with IE7 all is well but in Firefox when I attempt to upload a file to the server it displays an HTTP authentication prompt - which even if given the correct details, simply stalls the upload process.
I believe the reason IE7 is ok is down to the the session / authentication information being shared by the browser and the Flash component - however, in Firefox this is not the case and I experience the above behaviour.
Here is my updated upload function, incorporating your changes:
private function pergress():void
{
if (fileCollection.length == 0)
{
var urlString:String = "upload_process.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&filetotal="+fileTotal;
if (ExternalInterface.available)
{
ExternalInterface.call("uploadComplete", urlString);
}
}
if (fileCollection.length > 0)
{
fileTotal++;
var urlRequest:URLRequest = new URLRequest("upload_file.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&obfuscate="+obfuscateHash+"&sessidpass="+sessionPass);
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = new URLVariables("name=Bryn+Jones");
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("testuser:testpass");
var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
urlRequest.requestHeaders.push(credsHeader);
file = FileReference(fileCollection.getItemAt(0));
file.addEventListener(Event.COMPLETE, completeHandler);
file.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);
file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
file.upload(urlRequest);
}
}
As stated above, I seem to be experiencing the same results with or without the amendments to my function.
Can I ask also where the crossdomain.xml should be located - as I do not currently have one and am unsure where to place it.
The syntax is a little different for URLRequest, but the idea's the same:
private function doWork():void
{
var req:URLRequest = new URLRequest("http://yoursite.com/yourservice.ext");
req.method = URLRequestMethod.POST;
req.data = new URLVariables("name=John+Doe");
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("yourusername:yourpassword");
var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
req.requestHeaders.push(credsHeader);
var loader:URLLoader = new URLLoader();
loader.load(req);
}
A couple of things to keep in mind:
Best I can tell, for some reason, this only works where request method is POST; the headers don't get set with GET requests.
Interestingly, it also fails unless at least one URLVariables name-value pair gets packaged with the request, as indicated above. That's why many of the examples you see out there (including mine) attach "name=John+Doe" -- it's just a placeholder for some data that URLRequest seems to require when setting any custom HTTP headers. Without it, even a properly authenticated POST request will also fail.
Apparently, Flash player version 9.0.115.0 completely blocks all Authorization headers (more information on this one here), so you'll probably want to keep that in mind, too.
You'll almost surely have to modify your crossdomain.xml file to accommodate the header(s) you're going to be sending. In my case, I'm using this, which is a rather wide-open policy file in that it accepts from any domain, so in your case, you might want to limit things a bit more, depending on how security-conscious you are.
crossdomain.xml:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-http-request-headers-from domain="*" headers="Authorization" />
</cross-domain-policy>
... and that seems to work; more information on this one is available from Adobe here).
The code above was tested with Flash player 10 (with debug & release SWFs), so it should work for you, but I wanted to update my original post to include all this extra info in case you run into any issues, as the chances seem (sadly) likely that you will.
Hope it helps! Good luck. I'll keep an eye out for comments.
The FileReference.upload() and FileReference.download() methods do not support the URLRequest.requestHeaders parameter.
http://livedocs.adobe.com/flex/2/langref/flash/net/URLRequest.html
If you want to upload a file, you just need to send the correct headers and the content of file using URLRequest via UploadPostHelper class. This works 100%, i am using this class to upload generated images and CSV files, but you could upload any kind of file.
This class simply prepares the request with headers and content as if you would be uploading the file from a html form.
http://code.google.com/p/as3asclublib/source/browse/trunk/net/UploadPostHelper.as?r=118
_urlRequest = new URLRequest(url);
_urlRequest.data = "LoG";
_urlRequest.method = URLRequestMethod.POST;
_urlRequest.requestHeaders.push(new URLRequestHeader("X-HTTP-Code-Override", "true"));
_urlRequest.requestHeaders.push(new URLRequestHeader("pragma", "no-cache"));
initCredentials();
_loader.dataFormat = URLLoaderDataFormat.BINARY;
//this creates a security problem, putting the content type in the headers bypasses this problem
//_urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
_urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
_urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary()));
_urlRequest.data = UploadPostHelper.getPostData("file.csv", param[1]);
_loader.load(_urlRequest);
I'm not sure about this but have you tried adding username:password# to the beginning of your url?
"http://username:password#yoursite.com/yourservice.ext"
var service : HTTPService = new HTTPService ();
var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false;
encoder.encode("user:password");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.method = HTTPRequestMessage.POST_METHOD;
service.request = new URLVariables("name=John+Doe");
service.addEventListener(FaultEvent.FAULT,error_handler );
service.addEventListener(ResultEvent.RESULT,result_handler);
service.url = 'http://blah.blah.xml?'+UIDUtil.createUID();
service.send();
Seemingly similar problem was solved here. I urge you to also check the Flexcoders post linked to in the first post.
The problem was that FireFox uses a separate browser window instance to send the file upload request. The solution is to manually attach the session id to the request url. The session id is not attached as a regular GET variable, but with a semicolon (the reason for this syntax is unknown to me).
Flash is very limited in terms of what sort of headers you can pass with an http request (and it changes between browsers and OSes). If you get this to work on one browser/OS, make sure you test it on the others.
The best thing to do is not mess with HTTP headers.
We have the same issue (uploading to Picasa Web Albums from flash) and post through a proxy on our server. We pass the extra headers through as post parameters and our proxy does the right thing.
"http://username:password#yoursite.com/yourservice.ext"
This doesn't work in IE (http://www.theregister.co.uk/2004/01/30/ms_drop_authentication_technique/) and doesn't seem to work in Chrome either.
probably not usable in Flash
Here is a work-around when using ASP.Net based in part on the work here.
I built a component that dynamically writes Flex objects to the page so they can be used in UpdatePanels. Message me if you want they code. To solve the above problem in pages where authentication cookies will need to be sent by URLRequest, I add the values in as flashVars.
This code only works in my object, but you get the idea
Dictionary<string, string> flashVars = new Dictionary<string, string>();
flashVars.Add("auth", Request.Cookies["LOOKINGGLASSFORMSAUTH"].Value);
flashVars.Add("sess", Request.Cookies["ASP.NET_SessionId"].Value);
myFlexObject.SetFlashVars(flashVars);
Then in the Flex Object, check for the params
if (Application.application.parameters.sess != null)
sendVars.sess= Application.application.parameters.sess;
if (Application.application.parameters.auth != null)
sendVars.au= Application.application.parameters.auth;
request.data = sendVars;
request.url = url;
request.method = URLRequestMethod.POST;
Finally stuff the cookies in on global.asax BeginRequest
if (Request.RequestType=="POST" && Request.Path.EndsWith("upload.aspx"))
{
try
{
string session_param_name = "sess";
string session_cookie_name = "ASP.NET_SESSIONID";
string session_value = Request.Form[session_param_name]; // ?? Request.QueryString[session_param_name];
if (session_value != null) { UpdateCookie(session_cookie_name, session_value); }
}
catch (Exception) { }
try
{
string auth_param_name = "au";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
string auth_value = Request.Form[auth_param_name];// ?? Request.QueryString[auth_param_name];
if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); }
}
catch (Exception) { }
}
Hope this help someone avoid the 6 hours I just spent addressing this. Adobe has closed the issue as unresolvable, so this was my last resort.
I'm trying to request a HTTP resource that requires basic authorization headers from within an Adobe AIR application. I've tried manually adding the headers to the request, as well as using the setRemoteCredentials() method to set them, to no avail.
Here's the code:
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
private function authAndSend(service:HTTPService):void
{
service.setRemoteCredentials('someusername', 'somepassword');
service.send();
}
private function resultHandler(event:ResultEvent):void
{
apiResult.text = event.result.toString();
}
private function resultFailed(event:FaultEvent):void
{
apiResult.text = event.fault.toString();
}
]]>
</mx:Script>
<mx:HTTPService id="apiService"
url="https://mywebservice.com/someFileThatRequiresBasicAuth.xml"
resultFormat="text"
result="resultHandler(event)"
fault="resultFailed(event)" />
<mx:Button id="apiButton"
label="Test API Command"
click="authAndSend(apiService)" />
<mx:TextArea id="apiResult" />
However, a standard basic auth dialog box still pops up prompting the user for their username and password. I have a feeling I'm not doing this the right way, but all the info I could find (Flex docs, blogs, Google, etc.) either hasn't worked or was too vague to help.
Any black magic, oh Flex gurus? Thanks.
EDIT: Changing setRemoteCredentials() to setCredentials() yields the following ActionScript error:
[MessagingError message='Authentication not supported on DirectHTTPChannel (no proxy).']
EDIT: Problem solved, after some attention from Adobe. See the posts below for a full explanation. This code will work for HTTP Authentication headers of arbitrary length.
import mx.utils.Base64Encoder;
private function authAndSend(service:HTTPService):void
{
var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false; // see below for why you need to do this
encoder.encode("someusername:somepassword");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.send();
}
Finally received some attention from Adobe and got an answer on this. The problem with long HTTP Authentication headers is that, by default, the Base64Encoder class will inject newline characters every 72 characters. Obviously that causes a chunk of the base-64 encoded string to be interpreted as a new header attribute, which causes the error.
You can fix this by setting (in the above example) encoder.insertNewLines = false; The default setting is true.
I've fixed the above code to work for arbitrarily long Authentication strings.
Ah. The pain, the suffering. The sheer misery.
While you've figured out how to add a header before making your call, the nasty truth is that somewhere deep down in the Flash/browser integration space your headers are being removed again.
From my blogpost last year at verveguy.blogspot.com
So I have unraveled the Truth. (I think)
It's more tortured than one would imagine
1/ All HTTP GET requests are stripped of headers. It's not in the Flex stack so it's probably the underlying Flash player runtime
2/ All HTTP GET requests that have content type other than application/x-www-form-urlencoded are turned into POST requests
3/ All HTTP POST requests that have no actual posted data are turned into GET requests. See 1/ and 2/
4/ All HTTP PUT and HTTP DELETE requests are turned into POST requests. This appears to be a browser limitation that the Flash player is stuck with. (?)
What this boils down to in practical terms is that if you want to pass headers in all requests, you should always use POST and you should find another way to communicate the semantics of the operation you "really wanted". The Rails community have settled on passing ?_method=PUT/DELETE as a work around for the browser problems underlying 4/
Since Flash adds the wonderful header stripping pain on GET, I'm also using ?_method=GET as a workaround for that. However, since this trips up on 3/,
I am passing a dummy object as the encoded POST data. Which means my service needs to ignore dummy posted data on a ?_method=GET request.
Crucial at this point to know about 2/. That wasted a bunch of my time.
I've built all of this handling into a new RESTService class with MXML markup support so it's possible to pretend this doesn't exist on the client side.
Hope this helps someone.
The setCredentials() & setRemoteCredentials() methods are intended for use with Flex/LiveCycle Data Services, so they probably don't apply in your case.
This ought to work for you. I was able to reproduce this behavior on my server, and this fix seems to have done the trick; it still seems a bit odd this isn't more API-user-friendly, considering how common a use case you'd think it were, but nonetheless, I've tested and verified this works, given a valid SSL cert:
private function authAndSend(service:HTTPService):void
{
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("someusername:somepassword");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.send();
}
Hope it helps! And thanks for posting -- I'm sure I would've run into this one sooner or later myself. ;)
This really has helped me! Thanks!
I use Flex Builder 3
One note: WebService's property headers is read only.
So I tried to use httpHeaders. It works!
var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false;
encoder.encode("test:test");
sfWS.httpHeaders = {Authorization:"Basic " + encoder.toString()};
I had the same problem while consuming HTTP Basic Authenticated Webservice. This is my solution; it works fine:
private function authAndSend(service:WebService):void
{
var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false;
encoder.encode("user:password");
service.httpHeaders = { Authorization:"Basic " + encoder.ToString() };
service.initialize();
}
usage
authAndSend(WebService( aWebServiceWrapper.serviceControl));
Try using setCredentials rather than setRemoteCredentials and failing that, using Fiddler/Charles to find out what headers are being sent with the request.
Also, just so other people don't spend 10 minutes working out why the correct example doesn't quite work asis, you need to import the mx.utils.Base64Encoder package eg:
import mx.utils.Base64Encoder;
At the beginning or somewhere within the CDATA area. I'm new to flex so this wasn't quite obvious at first.
This is how its done.
import mx.utils.Base64Encoder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;
var _oHttp:HTTPService = new HTTPService;
var sUsername:String = "theusername"
var sPassword:String = "thepassword";
var oEncoder:Base64Encoder = new Base64Encoder();
oEncoder.insertNewLines = false;
oEncoder.encode(sUsername + ":" + sPassword);
_oHttp.method = "POST";
_oHttp.headers = {Authorization:"Basic " + oEncoder.toString()};
in the following code :
var benq:Base64Encoder = new Base64Encoder();
benq.encode("force",0,5);
var tmp:String = benq.toString();
'tmp' turns out to be an empty string, i.e. with length 0.
why?
how to encode a string using base64encoder?
Are you sure that your code isn't working.
I just copied and pasted it into a test app and it returned tmp as 'Zm9yY2U='
Are you doing anything else to the var tmp? if debugging make sure that it has processed the var tmp:String.... line when your checking the output
<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white"
creationComplete="but1.label = encodeit()">
<mx:Script>
<![CDATA[
import mx.utils.Base64Encoder;
private function encodeit(): String {
var benq:Base64Encoder = new Base64Encoder();
benq.encode("force",0,5);
var tmp:String = benq.toString();
return tmp;
}
]]>
</mx:Script>
<mx:Button
id="but1"
width="100"
height="100"
/></mx:Application>
Are you using Flex 3, as it seems to be a new feature? Also try encoding into a bytearray using encodeBytes and using encodeUTFBytes, perhaps these work better.
Online reference is available from Adobe, but I guess you know that.
Ok, it is working.
The code that I posted was different from what I was actually using.
I skipped over the fact that calling toString() for Base64Encoder
clears its internal buffer. So, calling it the next time would return
an empty string.
Sorry for the trouble.