« HTTP Authentication for HTTP/GET requests using ActionScript 3 | Main | BarCamp Bangalore »
March 06, 2006
How to get URL query-string variables within Flex application
On flexcoders, someone asked, how to get the URL parameters in a Flex 2.0 application? By URL parameter, I mean the query-string variables, as shown below.
http://yourserver/yourapp.swf?name=Joe&age=22 or http://yourserver/yourapp.mxml?name=Joe&age=22 (requires server in place)
name and age are the query-string variables.
You can get the values of the params using from mx.core.Application.application.parameters object, which contains the name-value pairs (hash-map).
For example, mx.core.Application.application.parameters.name would return "Joe", considering above example URL.
You can find more information about this in livedocs: http://livedocs.macromedia.com/flex/20beta1/docs/00001300.html
Then someone asked, what if your swf is embedded in custom html wrapper, how to get the query-string params inside swf? Solution is to use ExternalInterface class in Macromedia Flash Player 8(onwards) to invoke some JavaScript functions and extract the value in ActionScript.
I wrote a quick-and-dirty class in ActionScript 3, which would get the values of params from URL query-string for you. You don't need any extra JavaScript code in HTML. The same logic can be used for any an ActionScript 2.0 running Macromedia Flash Player 8.
QueryString class has following properties:-
parameters- an Object which contains the name-value pairs from query-stringqueryString- String, this contains the entire query-string (url-encoded) name-value pairs.url- String, this returns the complete URL of the wrapper page with query-string.
Posted by Abdul Qabiz at March 6, 2006 01:15 PM
Comments
I like your site Mr. Abdul Qabiz. Thank you for your site, its quite the enjoyable read. Jolly good now.
Posted by: Lawrence Lai at March 27, 2006 09:16 AM
Jolly well done with the input strings, quite the systemic anomoly. Jolly good.
Posted by: Kenny Lim at March 27, 2006 09:19 AM
and in Flash(AS1 & AS2), you could do this by using the _url property.
Guess many would've known that?
Posted by: Arul Prasad at April 24, 2006 07:56 PM
Arul,
_url property returns the URL of the SWF. Which is the first case on above post. What I talked about is getting query-string which is passed to the wrapper page.
f.ex:
http://foo.com/page.htm?foo=var
You can get the foo=var name-value pair using above solution.
-abdul
Posted by: Abdul Qabiz at April 25, 2006 12:45 AM
So is the javascript required, or does your AS do all the work internally (if so, nice!)
Posted by: Bret Stevens at May 1, 2006 09:57 PM
You don't need any javascript code. AS takes care of everything.
-abdul
Posted by: Abdul Qabiz at May 2, 2006 06:08 PM
This is less of a comment and more of an offer. You have no listed email address, so I thought that this would be the best way to get a hold of you.
Your actionscript was exactly what I've been looking for. My friend and I have had this idea for his local record label for quite some time: if he could put a flash movie on the root of his site (his homepage), as visitors come to to the root from other pages for his bands, the flash movie could read the bandID url parameter and write it to a text file. The movie could then use that text file to show a list of the most recent bands visited by displaying the picture associated with that bandID (i.e. http://www.recordlabel.org/bandID01.jpg). Do you think this is possible using flash? If so, would you like to earn some money to develop it? I have no doubt he would pay for your services, and I'd pitch in too cause I'd like to mod it out and use it for some other things. We're just a couple of kids, but if you're interested, we could pay you via paypal before the work is started. If not, thanks for your time anyways.
Posted by: Jason at May 3, 2006 10:05 AM
if it were PHP it would be much easier (there's a special function for it). But we have what we have (thanks for the post nonetheless)
Posted by: Chanel Rachel at May 29, 2006 08:25 PM
Can this work in Mx 2004?
thxs
Posted by: Chris at June 2, 2006 05:05 AM
Yeah, you can make it work in Flash Player 7. Using Flash JavaScript gateway or my JSCommunicator Library insted of using ExternalInterface.
You can use similar technique.
-abdul
Posted by: Abdul Qabiz at June 2, 2006 06:54 PM
So is there any way to get the Variables from the Present URL with nothing else execpt for flash. You think that it would have it implamented but it dosent. Or does it? Is there a way to retrive it without any Java or anything more like for instants MYSPACE filters out Java :-\
Posted by: Keld at June 11, 2006 10:23 AM
hmm, if you are using Flash Player 9, then you should be able to do that.
If you are using JavaScript (SWFObject) to embed Flash application in your html page, then you should be able to do that and pass things via FlashVars.
-abdul
Posted by: Abdul Qabiz at June 14, 2006 09:22 PM
hmm, if you are using Flash Player 9, then you should be able to do that.
If you are using JavaScript (SWFObject) to embed Flash application in your html page, then you should be able to do that and pass things via FlashVars.
-abdul
Posted by: Abdul Qabiz at June 15, 2006 09:36 AM
But Ive only got flash player 8, what can I do ?
Katoey
Posted by: katoey at June 20, 2006 05:20 AM
I was able to simplify the conversion method (still compatible with ActionScript 2.0) by using String.fromCharCode():
public function convert
(src:String):String {
while(true) {
var i:Number = src.indexOf("%");
if (i==-1)
break;
var n:Number = parseInt("0x"+src.substr(i+1,2));
src = src.substr(0,i) + String.fromCharCode(n) + src.substr(i+3);
}
return src;
}
Posted by: jon at July 13, 2006 05:59 AM
Ah, fixed a minor bug: if there was a "%25" on the querystring, that would cause problem. Try "tester.html?text1=abc%25def" with the previous version and you would get the character represented by "%de"!.
My quickie fix is below:
private function convert(src:String):String {
var i:Number = src.indexOf("%25"); // look for %25, which is the percent-sign
if (-1 != i) {
// if we convert a percent-sign in-line, that will confuse
// our simple parser. Let's replace it with a sentinel.
src = src.substr(0,i) + "[Yz" + src.substr(i+3);
}
while(true) {
i = src.indexOf("%");
if (i==-1)
break;
var n:Number = parseInt("0x"+src.substr(i+1,2));
src = src.substr(0,i) + String.fromCharCode(n) + src.substr(i+3);
}
i = src.indexOf("[Yz"); // look for sentinel
if (-1 != i) {
src = src.substr(0,i) + "%" + src.substr(i+3);
}
return src;
}
Posted by: jon at July 13, 2006 06:18 AM
Thank's for you function.
Posted by: wendelmaques at October 4, 2006 03:29 AM
Thanks my friend.. :)
Posted by: Anz at January 2, 2007 04:39 PM
Hi, is the flashboject.js file required? If yes, then this statement isn't entirely correct:
"You don't need any extra JavaScript code in HTML."
Embedding a JS file is equivalent to having extra JS code in your HTML.
Posted by: Tesla at January 11, 2007 12:38 PM
I just downloaded and tested out your demo. It looks like the JS file is not required, which put a big smile to my face. Thanks, it's a very useful class and if I ever use it you will be given credit. Good job.
Posted by: Tesla at January 11, 2007 01:02 PM
ANZ, flashobject.js is needed only for including flash object.
Posted by: mico at January 24, 2007 04:51 PM
Thank's very useful.
Posted by: Xplane at February 1, 2007 11:28 PM
Has anyone found a way to get the URL when allowScriptAccess="never" (like on MySpace.com).
ExternalInterface.call() throws a SecurityError: Error #2060
The code below always throws an error when embeded on MySpace.com, or a similar site that sets allowScriptAccess to never.
CODE
/CODE
Posted by: Jason Hanson at February 23, 2007 09:53 AM
> ExternalInterface.call() throws a SecurityError:
> Error #2060
That is intentional to have more security. Myspace (or alike sites) have faced serious security threats in past...Cross-site-scripting stuff...
I am not sure, if there is a way...
-abdul
Posted by: Abdul Qabiz at February 23, 2007 01:11 PM
Thanks for the reply Abdul. I have been trying to find a work around to this for a few days straight now. The interesting thing is that the Flash player *knows* what page it is on. When you attempt to run any ExternalInterface.call() inside a try / catch the error that is thrown contains a message similar to: "Sandbox security error: The swf at domain http://jason.com cannot access the page at http://www.myspace.com.
When I found this I was happy and just parsed through the error message with RegEx to pull out the URL. (I only need the URL for tracking purposes - I want to know what sites my SWF ends up on). However, and this is a big however, the error message ONLY contains the stack trace with the URLS of the error when in the Debugger Player.
This does not work in the retail consumer version of the player. Flash player knows the URL of the page it is on even when allowScriptAccess="never". I just want to find a way to capture that error message or some other way to get the page it is on - or even just the domain it is in.
Thanks for any ideas you have!
Also, I have been looking for the source of ExternalInterface.as so get a better idea of how to intercept the error it throws. Do you know where I could get that - it is in the playerglobal.swc.
thanks a ton!
--jason
Posted by: Jason Hanson at February 23, 2007 09:12 PM
I just need to get the domain name. I will have user embedded content so I can't use any JavaScript.
Posted by: Andrew Paul Simmons at June 25, 2007 03:02 AM
Thank you so very much for posting this and giving us the ability to download your code. It has helped me very much. I will be visiting your site much more.
Posted by: rob capilli at August 8, 2007 08:25 PM
@jon: Thanks for code changes and suggestions.
@jason, Andrew: I am not able to think total client-side (actionscript/flash) find the domain/page name that embeds SWF, if allowScriptAccess is not allowed. However, I can tell you other way that requires a server-side script...
<embed src="http://yourserver.com/getSWF.php" .. />
Where, getSWF.php might return something like this:-
yourapp.swf?referer=
If you serve your SWF through a PHP file, you can capture HTTP_REFERRER on server-side and pass it via query-param of SWF (if it has to go to SWF) or store in DB to track who is referring your APPS.
Does it make sense?
-abdul
Posted by: Abdul Qabiz at August 20, 2007 11:22 PM
Can you contact me if you are your compnay is doing Flex development? I am a developer and I need assistance getting some things in Flex to work even though they are things that should just work.
Posted by: Darren at August 22, 2007 06:35 PM
Hi Abdul,
I'm new to flex so please bear with me. I have a static HTML page that embeds Flex swf file and I pass one parameter to it.
like:
Test.swf?id=567
both in embed src and movie value.
I tried your example but it does not seem to work for me.
Any help is highly appreciated.
Thanks,
Mahe
Posted by: Mahesh at August 24, 2007 04:55 AM
@Mahesh: QueryString class is not for getting there parameters passed to SWF via FlashVars or as query-string (as you mentioned). There is built-in support for your use-case. If you are using Flex, you can look at Application.application.parameters object for such properties, if you are using Flash, you can get the query-string passed as properties in stage - AS3 and _level0 - AS2....
Does it make sense?
-abdul
Posted by: Abdul Qabiz at August 24, 2007 01:48 PM
Hi abdul,
i am new to flex. in my application i am just passing the url inside navigateToURL ie var urlRequest:URLRequest = new URLRequest("http://localhost:8080/MyApp.swf?securityId=7");
navigateToURL(urlRequest,"_self");
.and when MyApp.swf loads in the creationComplete i am trying to access the securityId by mx.core.Application.application.parameters.securityId.
but this shows the result as "undefined".
please help.
Posted by: Subrat at October 4, 2007 12:11 PM
Wow. Never thought of doing it with ExternalInterface.
Simple, yet effective.
Thanks a ton!
Posted by: DaDDeL at October 19, 2007 01:44 AM
For all of you that can't get it to work, make sure that you param "allowScriptAccess" in your html embbeding flash is set to "always" if testing from your computer. it should work with "sameDomain" if tested from your server.
And just a thought to eliminate all string parsing, you could just use URLVariables to decode the querystring. so this code:
{
_params = {};
try
{
_all = ExternalInterface.call("window.location.href.toString");
_queryString = ExternalInterface.call("window.location.search.substring", 1);
if(_queryString)
{
var params:Array = _queryString.split('&');
var length:uint = params.length;
for (var i:uint=0,index:int=-1; i
{
var kvPair:String = params[i];
if((index = kvPair.indexOf("=")) > 0)
{
var key:String = kvPair.substring(0,index);
var value:String = kvPair.substring(index+1);
_params[key] = value;
}
}
}
}catch(e:Error) { trace("Some error occured. ExternalInterface doesn't work in Standalone player."); }
}
would look like this:
private function readQueryString():void
{
_params = {};
try
{
_all = ExternalInterface.call("window.location.href.toString");
_queryString = ExternalInterface.call("window.location.search.substring", 1);
_params = new URLVariables(_queryString);
}catch(e:Error) { trace("Some error occured. ExternalInterface doesn't work in Standalone player."); }
}
and dont forget to import flash.net.URLVariables and to change the Object to URLVariables for _params.
Really neat class though. very useful.
Posted by: Kinsley at October 25, 2007 01:51 AM
@Kinsley: Thanks, when I wrote this code I am not sure URLVariable class was there, I wrote it for first public beta of Flex 2. I would update the code to avoid loop, though URLVariables would be doing the same internally.
-abdul
Posted by: Abdul Qabiz at October 25, 2007 09:56 AM
Hi any one help me. How i fetch current URL of the HTML page in flash widget.
Posted by: guru at October 26, 2007 02:23 PM
@guru: Since html page is in different domain, this code might not work because it requires html and swf in same domain or allowScriptAccess=always|sameDomain.
However, you can find about the html page using HTTP referer. Serve your flash-widgets through a server-side script, capture the header and pass it to SWF using flashvars or query string..
http://yourserver.com/getWidget.php?id=foo
Above URL can do a HTTP 30x redirection to
http://yourserver.som/widget.swf?referer=http://otherserver.com/somepage.html
http://otherserver.com/somepage.html is embedding the SWF..
Does that make sense?
-abdul
Posted by: Abdul Qabiz at October 26, 2007 03:25 PM
Hi Abdul,
I think the URLVariables solution given by DaDDeL is more good because it will automatically take care of url decoding.
Thanks for the structured and uselful class..
Best Regards
Anz
Posted by: Anz at November 1, 2007 05:05 PM
how do i do the exact opposite of what you did. i need to send a url-encoded string to a server. i can't get the variable to be a string...it deciphers my "&" and "=" into %3d etc.
i use URLVariables, URLRequest, and a URLLoader?? i don't need to load anything...just POST some info in a URLencoded string.
THANKS!
Posted by: gena at November 8, 2007 03:53 AM
Oooh Abdul!
Do you remember the axe advertising???
Of course you do.
Like it ;)
Posted by: tom at November 13, 2007 02:32 AM
dude this site rox !
found asnwers here that that cudnt anywhere
Good job , keep the site running :D
Posted by: Fahad at November 28, 2007 01:28 PM
Did anyone ever get around the flash allowScriptAccess problem?
Posted by: Jason at December 7, 2007 01:48 PM
Hello.
Need a bit help, I am setting a variable in flex application. and pasing a xml file name from flashvars from HTML. If I direct give the file name it shows the data in gridtable but while passing it is not taking. here is the code::
Code for MXML file ::
----
-
-
- xmlns:mx="http://www.adobe.com/2006/mxml"
- width="100%" height="100%"
- creationComplete="bs.send();">
-
-
- import mx.managers.CursorManager;
- import mx.rpc.events.InvokeEvent;
- import mx.controls.Alert;
- import mx.rpc.events.FaultEvent;
- import mx.rpc.events.ResultEvent;
- import mx.collections.ArrayCollection;
- public var xmlFile:String; //="xml/tableGrid.xml";
- [Bindable]
- private var bloggersCol:ArrayCollection;
- // Gets called when HTTPService is invoked to
- // request the XML.
- private function bsInvokeHandler(event:InvokeEvent):void
- {
- // Display the busy cursor
- CursorManager.setBusyCursor();
- }
- // Gets called when the XML is successfully loaded.
- private function bsResultHandler(event:ResultEvent):void
- {
- // Save a reference to the list of bloggers
- bloggersCol = event.result.tableGrid.manthan;
- // Hide the busy cursor
- CursorManager.removeBusyCursor();
- }
- private function bsFaultHandler(event:FaultEvent):void
- {
- // There was an error in loading the XML
- Alert.show (event.fault.message);
- // Hide the busy cursor
- CursorManager.removeBusyCursor();
- }
- ]]>
-
-
-
- concurrency="single"
- contentType="application/xml"
- resultFormat="flashvars"
- showBusyCursor="true"
- id="bs" useProxy="false"
- url="{xmlFile}"
- invoke="bsInvokeHandler(event);"
- result="bsResultHandler(event);"
- fault="bsFaultHandler(event);"
- >
-
-
-
-
----
code for HTML ::
-
id="topBar" width="100%" height="100%"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
-
-
-
-
-
-
- flashvars = "xmlFile=xml/tableGrid.xml"
- width="100%" height="100%" name="topBar" align="middle"
- play="true"
- loop="false"
- quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
-
- ----
-----
--------------------
it is giving error :: faultCode:Client.URLRequired faultString:'A URL must be specified with useProxy set to false.' faultDetail:'null'
can you please tell me where I am doing mistake.
Thx
Anoop Sharma
Posted by: Anoop Sharma at December 12, 2007 08:27 PM
link to adobe live is broken
Posted by: Justin at December 20, 2007 10:22 AM
@Justin: Thanks, this article was posted during Flex 2 Beta time.. Link is down, I would correct it.
-abdul
Posted by: Abdul Qabiz at December 20, 2007 09:08 PM
Hello Abdul.
I read your comments and got several solutions from here. I stuck again, the problem is:
when I give a XML file name with path (ie: xml/tableGrid.xml) in MXML it works fine with HTTPService method. But when I am passing the XML file name through Flashvars it is giving error "UseProxy set to flase" which I alerady did. Alert shows the name of teh file correctly, SO passing name from flashvars is not a problem but why I am not getting the data in dataGrid from that XML??
Also if I put direct xml data in a variable and pass it through flashvars it is showing fine in DtatGrid without even HTTPService method. But I have to pass data from external XML File.
Where I am doing mistake , can You plese give some comment on this.
Thx
Anoop
Posted by: Anoop at December 31, 2007 11:27 AM
You can't get URLs from Myspace/Facebook because of allowscriptaccess never. Please vote to fix the bug below so we have this information everywhere.
The browser URL information is actually available in the Error Code returned from a call to ExternalInterface (when Javascript is not allowed). This information is not available in the standard player (but is in the debug), ARGH…. We all want to track our Flash widgets so please vote to fix this bug. You would then be able to get the browser URL from the Error code returned on the API call from Myspace page (a bit of a hack but the information would be available).
http://bugs.adobe.com/jira/browse/ASC-3095
Posted by: jason at January 18, 2008 04:31 AM
This site also provides a way to get the url parameters in actionscript: http://www.flexpasta.com/index.php/2008/03/15/getting-url-parameters-host-name-port-in-flex-actionscript/
Posted by: Steve at March 15, 2008 10:12 PM
Hi,
I have downloaded your code.
But whenever i try to give parameters in url like this :
"C:\Documents and Settings\jigaro\Desktop\ParamTesting\bin\ParamTesting.html?myName=Jigar&myHomeTown=Ahmedabad"
I am getting following error :
Windows cannot find 'C:\Documents and Settings\jigaro\Desktop\ParamTesting\bin\ParamTesting.html?myName=Jigar&myHomeTown=Ahmedabad'. Check the spelling and try again, or try searching for the item by clicking the Start button and then clicking Search.
What should i do now?
Posted by: Jigar Oza at March 17, 2008 12:18 PM
Hey Adbul,
Great Blog, I've learned a lot already! I really love this QueryString class you've written. Would you mind if I used some of it in a similar how to post for flash but rewriting it for as2?
I'll send you a link soon...
Thanks again and keep it up!
Posted by: Evan Mullins at March 21, 2008 04:42 AM
Abdul,
Thanks this is a great site, I've learned a lot already. I thought your QueryString class was very intuitive and easy to use. I wanted to let you know I actually liked it so much I ported it back to as2. And I figured I'd share that as well, so it's at my blog post here, Get Current URL and Query String Parameters to Flash. Just to let you know!
Thanks again for the class,
Evan @ Circlecube.com
Posted by: Evan Mullins at March 21, 2008 11:07 AM
Hi..i am trying to do fileuplaod from flex to java servlet..problem is request is not coming to servlet..If I use jsp instead of servlet then request is coming to jsp..am not sure what's wrong with srvlet approach..any help woudl be appreciated
here is my code:
here is my servlet
...................
package com.boa.flex.servlet;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author nbkzk5e
*
*/
public class UploadFileServlet extends HttpServlet
{
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
private static final Log log = LogFactory.getLog(UploadFileServlet.class);
//@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
doPost(req,resp);
}
//@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
log.info("am in servlet");
log.info("author"+req);
File disk = null;
FileItem item = null;
FileItemFactory factory = new DiskFileItemFactory();
Iterator iter = null;
List items = null;
ServletFileUpload upload = new ServletFileUpload( factory );
ServletOutputStream out = null;
try
{
// Parse the incoming HTTP request
// Commons takes over incoming request at this point
// Get an iterator for all the data that was sent
// TODO: Leverage generics
log.info("am in servlet");
items = upload.parseRequest( req );
iter = items.iterator();
// Set a response content type
res.setContentType( "text/xml" );
// Setup the output stream for the return XML data
out = res.getOutputStream();
out.println( "" );
// Iterate through the incoming request data
while( iter.hasNext() )
{
// Get the current item in the iteration
item = ( FileItem )iter.next();
// If the current item is an HTML form field
if( item.isFormField() )
{
// Return an XML node with the field name and value
out.println( "" );
// If the current item is file data
} else {
// Specify where on disk to write the file
// Using a servlet init param to specify location on disk
// Write the file data to disk
// TODO: Place restrictions on upload data
disk = new File( "C:\\"+item.getName() );
log.info("am after disk");
item.write( disk );
// Return an XML node with the file name and size (in bytes)
out.println( "" );
}
}
// Close off the response XML data and stream
out.println( "" );
out.close();
// Rudimentary handling of any exceptions
// TODO: Something useful if an error occurs
} catch( FileUploadException fue ) {
fue.printStackTrace();
} catch( IOException ioe ) {
log.info("io error");
ioe.printStackTrace();
} catch( Exception e ) {
e.printStackTrace();
}
}
}
here is web.xml
.................
XFireServlet
org.codehaus.xfire.transport.http.XFireConfigurableServlet
XFireServlet
/servlet/XFireServlet/*
XFireServlet
/services/*
FileServlet
com.boa.flex.servlet.UploadFileServlet
FileServlet
/action/*
Posted by: baji at March 21, 2008 09:42 PM
@Evans: Thanks. Please feel free to use this code in whatever way you want to.
@Baji: I can't see flex code, please post it again enclosed by <pre>yourcode</pre>
Posted by: Abdul Qabiz at March 22, 2008 03:52 AM
@Steve: I think you aren't running the code inside a webserver. Try running it on localhost, or place it on your webserver (or install LAMP/WAMP/MAMP for a quick Apache/Mysql environment on you local machine)
Posted by: glenn at March 28, 2008 04:36 AM