AS3 AIR URLLoader POST - actionscript-3

I am developing my first AIR app (moving over from PHP/Javascript) and am at a stage where I want to send some data from the app back to a PHP script on my server. I have the following:
var url:String = "PHP URL HERE";
var request:URLRequest = new URLRequest(url);
var requestVars:URLVariables = new URLVariables();
requestVars.test = "1234";
request.data = requestVars;
request.method = URLRequestMethod.POST;
request.contentType = "application/xml;charset=utf-8";
var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
urlLoader.addEventListener(Event.COMPLETE, processSERPS, false, 0, true);
urlLoader.load(request);
I did have something else in the server side PHP script originally but for debugging I just changed it to dump the REQUEST array.
With the code above it will simply return nothing:
Array
(
)
But if I change the request method to Get:
request.method = URLRequestMethod.GET;
I receive:
Array
(
[test] => 1234
)
Which tells me that the code is correct, it just isn't sending the post parameters for some reason.
I would just alter the code to use GET variables but unfortunately the data I need to send is too large hence the need for POST.
Any help appreciated!

For URLRequest.contentType:
If the value of the data property is a URLVariables object, the value
of contentType must be application/x-www-form-urlencoded.
This is the default value, so just removing your assignment should do it.

Related

getting POST using URLRequest + if statement syntax issue

I'm trying to get the reply from the address specified in var url:String, which is either 0 or 1. If the reply is 1 then it must set currentState = CallFailed (as seen below). The client compiles without error (using Adobe Flash Builder 4.6) and seems to successfully reach var url:String, but doesn't seem to be getting the response\and or my if statement is incorrect.
Actionscript:
// check to see if block.php replies 0 or 1
var url:String = "https://domain.com/block.php?postid=" + calleeInput.text + "";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
request.data = variables;
request.method = URLRequestMethod.POST;
navigateToURL(request);
if (request.data == 1)
{
// if reply is 1 then cancel the call
currentState = CallFailed;
return;
}
PHP:
PHP will echo 0 or 1 when block.php is loaded. It's not encoded in any format such as JSON\AJAX.
It seems you want data from the server. Perhaps the URLLoader class would be better?
var url:String = "https://domain.com/block.php?postid=" + calleeInput.text + "";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
request.data = variables;
request.method = URLRequestMethod.POST;
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener( Event.COMPLETE,
function( e:Event ) : void
{
// your response data will be here
// you'll have to verify the format
trace( e.target.data );
}
)
loader.load( request );
Put a breakpoint at the trace statement and check out the contents of e.target.data, and go from there
The purpose of navigateToURL() is to open the webbrowser, as stated in its documentation:
Opens or replaces a window in the application that contains the Flash Player container (usually a browser). In Adobe AIR, the function opens a URL in the default system web browser
In order to perform an request (without opening a browser, just the HTTP communication) you should use URLLoader.
The URLLoader class downloads data from a URL as text, binary data, or URL-encoded variables.
On a related note: your logic is not valid. The call to a server is asynchronous. You have to wait for the response to be returned before reasoning about the result.
The URLLoader class dispatches a number of Events that help you decide when the result of a request is returned or if there's a problem with it.

How post extra name value pairs with a binary data post in AS3?

Here I upload recorded sound to server, but I need to add file name and the user name who is uploading the file. But I don't know how I can to post extra name value pairs with a binary data post?
function onClick(e:MouseEvent)
{
var sba:ByteArray = mp3Encoder.mp3Data;
var req:URLRequest = new URLRequest(URL);
req.contentType = 'application/octet-stream';
req.method = URLRequestMethod.POST;
req.data = sba;
var loader:URLLoader = new URLLoader();
loader.addEventListener( ProgressEvent.PROGRESS, progressHandler );
loader.addEventListener( Event.COMPLETE, completeHandler );
loader.load( req );
}
To do something like that you're likely going to have to use a URLRequest header, check out this information here:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequestHeader.html
You can use multipart request for sending both types of data (binary and variables). Check out this answer about how to create it in AS3:
Send file from actionscript to servlet

Upload file to server in as3

How to upload a File to server in as3? I don't want to browse file by using FileReference.browse(). I tried using URLLoader to get the file and convert to byteArray but as I send it to server using URLVariables it gives IOError=2032. I want update database on the server. The structure would be like
email (string)
sqlite_db (Blob)
I have to send both of these variables inside one request. Any idea!
The upload process is made much easier by using the UploadPostHelper which is a great class to create multipart data forms:
ByteArray byteArray = [YOUR FILE DATA];
var urlRequest : URLRequest = new URLRequest();
urlRequest.url = 'http://your.server.com/destination';
urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
urlRequest.data =
UploadPostHelper.getPostData(
'filename.ext',
byteArray,
{
email:"emailParameter",
other:"otherParameter"
} );
urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
// create a loader & send the file to the server;
var urlLoader : URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load( urlRequest );
And of course you can listen to the complete event and pass back any information from your server. Hope that helps.

AS3 ByteArray " The supplied index is out of bounds" Error

I'm working on an application and I need to save an AS3 object to a db.
Here's what I'm doing:
private function getComplete(e:Event)
{
var getVars:URLVariables = new URLVariables(unescape(e.target.data));
var _saveData_obj = readObjectFromStringBytes( getVars.saveData);
// do something with the save data....
}
public function SaveGame() {
var _save_data:Object = _puzzle.dataForSaving;
var _serialized_string = escape(serializeToString(_save_data));
var _round_time = Math.round( _elapsed_time);
var _token = MD5.hash( _id +
_difficulty +
"mysomewhatsecretstringhere" +
_round_time );
var request:URLRequest =
new URLRequest( _home + 'savegame.php' );
request.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.saveData = _serialized_string;
variables.time = _round_time;
variables.id = _id;
variables.dif = _difficulty;
variables.token = _token;
request.data = variables;
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, postComplete);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
}
public function LoadGame() {
var request:URLRequest =
new URLRequest( _home + 'loadgame.php?id='+_id+"&dif="+_difficulty);
request.method = URLRequestMethod.GET;
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, getComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, netError);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
}
public static function serializeToString(value:Object):String{
if(value==null){
throw new Error("null isn't a legal serialization candidate");
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(value);
bytes.position = 0;
trace ("Saved: "+bytes.length);
var be:String = Base64.encodeByteArray(bytes);
return be;
}
public static function readObjectFromStringBytes(value:String):Object {
var result:ByteArray=Base64.decodeToByteArray( value) as ByteArray;
result.position = 0;
var the_obj:Object = result.readObject();
return the_obj
}
The problem is that I keep getting a "The supplied index is out of bounds" error when I try to read the object from the Base64 string.... I checked if the saved string and the loaded string are the same. Tried to save the Base64 string to a shared object and retrieve it - that works fine ... the only problem is when I save and load to/from the server.
Can you guys help me? What am I doing wrong?
Thanks.
try using ba.writeMultiByte(string, 'utf-8') and ba.readMultiByte(ba.bytesAvailable, 'utf-8') without converting to object
Ok, so it looks like we've come to a series of steps you can take to debug what's going on.
(In save game) make sure that unescape( variables ).saveData == _puzzle.dataForSaving. If this does not work, then your issue is with either escape or unescape. I have to admit
I am suspicious here, you should never need to escape data for a POST once it has been Base64 encoded (as3crypto's Base 64 encoding will return only one of these characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=. Those are all legit in a POST) and your URLLoader should take care of making it a legit request, so I have difficulty seeing the need.
It is more consistent (and more expected) to have escape and unescape both accept strings as parameters and return strings.
Instead of storing to the database and then retrieving, store to $_SESSION (or, if possible, just echo the value back). This will eliminate PHP as a possible culprit.
In PHP, make sure that $_POST['saveData'] == /* whatever you echo */. If it isn't, then you have a DB encoding issue. You need to make sure that whatever encoding is used in MySQL is the same as the one used in AS.
As an aside, when working with AS, you'll often find it easier to use $_REQUEST instead of $_POST or $_GET. Since the requests are more or less abstracted, the URLRequests of AS don't really need to worry about being RESTful, and it is a heck of a lot easier to work with than exclusively using POSTs.

Flash / App Engine request data encoding problem (GET works, POST fails)

I'm new to Flash and trying to communicate with an app engine server but I'm having some encoding problems.
var playerLoader:URLLoader = new URLLoader();
playerLoader.addEventListener( Event.COMPLETE, function(e:Event) { doStuff(); } );
var requestVars:URLVariables = new URLVariables();
requestVars.q = "åäö";
var urlRequest:URLRequest = new URLRequest( serverUrl );
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = requestVars;
playerLoader.load( urlRequest );
This does not work, gives me some encoding errors on the server side. But if I switch POST to GET it automagically works.
Any clues what's going on and how I could use POST?
Thanks!
As far as I know, Actionscript's HTTP requests will natively be encoded in UTF-8.
I have it working this way for spanish chars:
var url:String = "historia.php";
var request:URLRequest = new URLRequest(url);
var requestVars:URLVariables = new URLVariables();
var now:Date = new Date();
requestVars.historia = "áóíúéñÁÓÍÚÉÑ";
request.data = requestVars;
request.method = URLRequestMethod.POST;
var urlLoader:URLLoader = new URLLoader();
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
urlLoader.load(request);
And on the PHP side (resumed for clarity):
header ('Content-type: text/html; charset=utf-8');
if(isset($_POST['historia']) {
$historia = mysql_real_escape_string(utf8_decode($_POST['historia']));
$historia = filter_var($historia, FILTER_SANITIZE_STRING);
// insert into DB...
}
I use utf8_decode() because the database is not configured with encoding UTF-8.
How are you handling the request on the server side? Maybe the problem lies on the server side.