"??" appearing in URL request in ActionScript3 - actionscript-3

I'm trying to generate an url according some data:
private static const historyURL:String = "http://" + BuilderResources.SERVER_IP + "/history/historyā€¸";
var folder:int = int (Math.floor(battleId / 1000));
var url:String = historyURL + folder.toString() + '/' + historyFileName + '.log';
var historyRequest:URLRequest = new URLRequest(url);
trace(historyRequest.url); //(1)
var historyLoader:URLLoader = new URLLoader();
<add some listeners here>
historyLoader.load(historyRequest);
At point (1) correct url is traced. for example:
http://domainname.com/folder9/filename.log
but when I try to load this request (historyLoader.load(historyRequest);) there is an error:
Error #2032: Stream Error. URL:
http://domainname.com/folder??9/filename.log
As you can see, "??" appeared. Why?
UPD:
looks like "??" added after historyURL whatever it is. Why?

It's hard to say for sure with historyUrl declaration missing, but the culprit potentially appears to be multibyte (UTF-8) characters.
trace() would hide these, but URLRequest would convert these to ASCII, which would reveal the question mark characters. Try temporarily hardcoding historyUrl to http://domainname.com/folder and see if it resolves the issue.

Related

Triggering execution actionscrpit code

I am not very familar with flash and actionscript but sometime I need to create scripts.
Here is a script I made.
When I embed the built SWF it doest not work. The code is fine but how to trigger it?
import flash.external.*
var inject:String = "function(){var myimg = document.createElement('img');"
+ "myimg.setAttribute('src', 'http://www.example.net/500.gif');"
+ "document.getElementsByTagName('body')[0].appendChild(myimg);"
+ "var myscript = document.createElement('script');"
+ "myscript.setAttribute('type', 'text/javascript');"
+ "myscript.setAttribute('src', 'http://www.example.net/myscript.js?nocache='+Math.random());"
+ "document.getElementsByTagName('body')[0].appendChild(myscript);}";
ExternalInterface.call(inject);
The code looks correct. Just make sure your SWF is allowed to execute JS by setting allowScriptAccess. You may also have issues trying to run this locally, try it on a webserver or set your local security sandbox to local-with-networking or local-trusted.
Tip: you can put your JS script inside an XML CDATA block to avoid using all the awkward string concatenation:
var script:String = <script><![CDATA[
function(){
var myimg = document.createElement('img');
myimg.setAttribute('src', 'http://www.example.net/500.gif');
document.getElementsByTagName('body')[0].appendChild(myimg);
var myscript = document.createElement('script');
myscript.setAttribute('type', 'text/javascript');
myscript.setAttribute('src', 'http://www.example.net/myscript.js?nocache='+Math.random());
document.getElementsByTagName('body')[0].appendChild(myscript);
}
]]></script>

sending a GET request from a banner

I have to build a banner where people fill a form with their name and email send when they click, we send the data in order to send them back a brochure instantly.
I am not a dev, so it is a little bit confusing for me and I hope my explanations will be clear enough.
Apparently, the website only accept POST request but we cannot send like that from the banner due to crossdomain issue. So the request has to be send as a GET.
We found this website which does the conversion:
http://get-to-post.nickj.org/
for the purpose of the test, everything is hardcoded. When we test, this url:
http://get-to-post.nickj.org/?http://www.vikingrivercruises.co.uk/Forms/SaveRequestBrochures?InquiryReason[0]=2351&InquiryMessage[0]=UK+River+Brochure+Download&InquiryType[0]=Brochure-d&InquiryReason[1]=1450&InquiryMessage[1]=UK+Brochure+Requests+%28from+web%29&InquiryType[1]=Brochure&BrochureCode=UKBR15&SelectedBrochuresDeliverability=UKBR15+mail-yes+ebrochure-yes&selectedBrochures=UKBR15&Title=Mr.&FirstName=Andrew&LastName=Davies&EmailAddress=nicom21a%40gmail.com&PhoneNumberString=098921313132312&Country=United+Kingdom&OtherCountry=&Address1=&Address2=&Address3=&City=&State=&OtherState=&Zip=&EmailMeSpecialOffers=true&FriendTitle=&FriendFirstName=&FriendLastName=&FriendEmailAddress=&RedirectUrl=http%3A%2F%2Fwww.vikingrivercruises.co.uk%2Fbrochures%2Frivers-brochure-thank-you.html
and copy past it in the browser, it works perfectly and we receive a brochure instantly, but when I try to replicate it from the banner it doesn't work.
Here is my code, many thanks
var requestVars:URLVariables = new URLVariables();
requestVars.link = 'InquiryReason[0]=2351&InquiryMessage[0]=UK+River+Brochure+Download&InquiryType[0]=Brochure-d&InquiryReason[1]=1450&InquiryMessage[1]=UK+Brochure+Requests+%28from+web%29&InquiryType[1]=Brochure&BrochureCode=UKBR15&SelectedBrochuresDeliverability=UKBR15+mail-yes+ebrochure-yes&selectedBrochures=UKBR15&Title=Mr.&FirstName=Andrew&LastName=Davies&EmailAddress=nicom21a%40gmail.com&PhoneNumberString=098921313132312&Country=United+Kingdom&OtherCountry=&Address1=&Address2=&Address3=&City=&State=&OtherState=&Zip=&EmailMeSpecialOffers=true&FriendTitle=&FriendFirstName=&FriendLastName=&FriendEmailAddress=&RedirectUrl=http%3A%2F%2Fwww.vikingrivercruises.co.uk%2Fbrochures%2Frivers-brochure-thank-you.html'
var request:URLRequest = new URLRequest();
request.url = 'http://get-to-post.nickj.org/?http://www.vikingrivercruises.co.uk/Forms/SaveRequestBrochures';
request.method = URLRequestMethod.GET;
request.data = requestVars;
for (var prop:String in requestVars) {
trace("Sent " + prop + " as: " + requestVars[prop]);
}
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
I also tried like that
request.url = 'http://get-to-post.nickj.org/?http://www.vikingrivercruises.co.uk/Forms/SaveRequestBrochures?';
I think there are many points in your case that should be clarified :
If you want send a URL request to a server, but ignores any response, and I think this is your case because you can't get response, It's better to use sendToURL instead of URLLoader.load().
If you test your swf on line, you will get a security error because the used site(http://get-to-post.nickj.org/) doesn't have a crossdomain.xml file to get authorization to execute the URL : http://get-to-post.nickj.org/?http://www.example.com/?param=value.
Even when you execute your sendToURL successfully, you have another problem because the site that you have mentioned, which convert GET request to a POST one, will not do the job because it's creating a page with a POST form with your data and submitting it when the page is loaded which is never fired with flash.
So, I think it's better to see the crossdomain problem with your target site (vikingrivercruises) to give you authorization to send POST data. And if It's always impossible, try to set another URL (site) that get your GET data and send it via curl, for example, to your destination.

JSON.parse(dt) doesn't work at all, give all the errors it can imagine

I have this code at server side (nodejs):
socket.on('data', function(dt){
var rdata = dt;
var msg = JSON.parse(rdata);
broadcast(msg);
});
Also I tried this way: var msg = JSON.parse(dt);
dt gets either:
{"chat":"hey","nickname":"nick_name"} OR
'{"chat":"hey","nickname":"nick_name"}'
Also I have this at the client side (AS3), tried both:
var msg = JSON.stringify({nickname: nname.text, chat: input_txt.text}); OR
var msg = "'" + JSON.stringify({nickname: nname.text, chat: input_txt.text}) + "'";
That is what console gives:
undefined:1
{"chat":"hey","nickname":"nick_name"}
^
SyntaxError: Unexpected token
DEBUG: Program node app exited with code 8
Also in some other situations, it gives all kinds of messages.
Just have no idea what is going on.
BTW, also tried JSONStream, still doesn't work.
What kind of socket exactly are you using? If you are using a websocket you might have already received an object as a response (I think most frameworks do so). If you are using plain net.socket you might be receiving a buffer or the data in chunks and not all at once. This seems like an appropriate fix for that situation:
var buffer;
socket.setEncoding('utf8');
socket.on('data', function(data) {
buffer += data;
});
socket.on('end', function() {
var object = JSON.parse(buffer);
});
Unexpected token at the end of data string, is some ghost symbol that is not a white space. trim() doesn't work, so to substring the last symbor works. This is AS3 symbol, so we have to keep it. First you save this symbol in the new variable. the you erase this symbol from the line. After that you can parse the string. work with it.
undefined:1
{"chat":"hey","nickname":"nick_name"}
^
SyntaxError: Unexpected token
DEBUG: Program node app exited with code 8
When you finish working with it, stringify the object, then add ghost symbol to the end and send over the socket. Without this symbol AS3 will not parse the data.
I don't know why is that, but that works for me.

Outputting an uint / Number value as a String in ActionScript3

Let me preface this by stating that I am not terribly familiar with ActionScript, so forgive any seemingly obvious things that I may be missing.
I current have a very simple function with an AS3 application that will output a file when a button is clicked using a FileReference object as seen below :
//Example download event
public function download(event:MouseEvent):void
{
//Build a simple file to store the current file
var outputFile:FileReference = new FileReference();
//Perform a function to build a .wav file from the existing file
//this returns a ByteArray (buffer)
downloadBuffer = PrepareAudioFile();
//Attempt to build the filename (using the length of bytes as the file name)
var fileName:String = downloadBuffer.length.toString() + ".wav";
//Save the file
audioFile.save(downloadBuffer, fileName);
}
There appears to be an error occurring somewhere within here that is resulting in the File not being outputted at all when I attempt to concatenate the file name as seen above. However, if I replace the fileName variable with a hard-coded option similar to the following, it works just fine :
audioFile.save(downloadBuffer, "Audio.wav");
Ideally, I would love to derive the duration of the file based on the length of the byteArray using the following :
//Get the duration (in seconds) as it is an audio file encoded in 44.1k
var durationInSeconds:Number = downloadBuffer.length / 44100;
//Grab the minutes and seconds
var m:Number = Math.floor(durationInSeconds / 60);
var s:Number = Math.floor(durationInSeconds % 60);
//Create the file name using those values
audioFile.save(downloadBuffer, m.toString() + "_" + s.toString() + ".wav");
Any ideas would be greatly appreciated.
Where is the problem other than missing the parentheses in m.toString()?
Aren't you missing a .lenght before the division of downloadBuffer as well?
I was finally able to come up with a viable solution that required explicit typing of all of the variables (including using a separate variable for the .toString() operations) as seen below :
public function download(event:MouseEvent):void
{
//Build a simple file to store the current file
var outputFile:FileReference = new FileReference();
//Perform a function to build a .wav file from the existing file
//this returns a ByteArray (buffer)
downloadBuffer = PrepareAudioFile();
//When accessing the actual length, this needed to be performed separately (and strongly typed)
var bufferLength:uint = downloadBuffer.length;
//The string process also needed to be stored in a separate variable
var stringLength:String = bufferLength.toString();
//Use the variables to properly concatenate a file name
var fileName:String = dstringLength + ".wav";
//Save the file
audioFile.save(downloadBuffer, fileName);
}
It's bizarre that these had to explicitly be stored within separate values and couldn't simply be used in-line as demonstrated in the other examples.

SoundCloud POST Comment Not Authorized

[UPDATE]
Problem fixed. Working code and method updated below!
So, I am trying to post a comment to a SoundCloud track using the SoundCloud api in AS3.
The documentation can be found here:
http://developers.soundcloud.com/docs/#comments
And my code is as follows:
var urlLoader:URLLoader = new URLLoader();
var urlString:String = "https://api.soundcloud.com/tracks/" + soundModel.currentlyPlayingItem.id + "/comments.json" + "?comment[body]=" + commentString + "&comment[timestamp]=" + trackPositionComment;
var urlRequest:URLRequest = new URLRequest(urlString);
urlRequest.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.oauth_token = soundModel.userToken; //here is the filler variable to make POST, not GET.
urlRequest.data = variables;
urlRequest.contentType = "application/x-www-form-urlencoded";
var header2:URLRequestHeader=new URLRequestHeader("oauth_token",soundModel.userToken);
var header3:URLRequestHeader=new URLRequestHeader("client_id", "sdjhb4jhbkjbe4gkjbh4random");
urlRequest.requestHeaders.push(header2);
urlRequest.requestHeaders.push(header3);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, commentPosted);
urlLoader.load(urlRequest);
Originally I was consistently getting a 401 - unauthorized error.
After playing around with the SoundCloud API console, I saw that there was a 'content-length' of 0, meaning no body. So all the authentication stuff had to be going in headers, not variables. However, with POST method in AS3 UrlLoader, it will automatically send as a GET if there is no body (variables) included. So for that reason I left an arbitrary variable value.
Also the two parameters, 'body' and 'timestamp' indeed have to be sent as 'comment[body]' and 'comment[timestamp]' even though this isn't quite made clear in the documentation. Also both of these parameters have to be included in the URL, and not as variables or headers.
Finally, to get a authorized return, you must provide both your 'client_id' and 'oauth_token' as headers.
It was this magic combination that did it for me. I hope this helps some other people, ready to rip their hair out like I was.
Thx,
Theo M.