How to make a Loadvars sendAndLoad request from embedded swf in flex - apache-flex

I've developed a simple flex app with embedded swf. Basically swf use Loadvars to get data from particular database table. Ok, when I tested the flex app on localhost it is works fine and embedded swf make its sendAndLoad calls correctly.
But! When it is located on the web server swf not work correctly. I meant there is not returned values by sendAndLoad method.
Well, to make some points: questionContentLoadVars.img1 holds(return) the string from php call. This "img1" is an empty returned string only in Flex app placed in the web server otherwise it returns correct value from php call?
When gameplay22.swf is standallone works!
When gameplay22.swf is in HTML page works!
When gameplay22.swf is embedded in FLex and executed in LOCALHOST works!
But in the web server this embedded gameplay22.swf doesn`t works!
What is the problem with it?
//* here is flash(swf) part of gameplay22.swf file which is embedded in the Flex by SWFLOader(gameplay22.swf)
questionContentLoadVars = new LoadVars();
questionContentLoadVars.onLoad = function(success){
if (success){
slidingSvityk_mc.descripTA_mc.description_ta.text = questionContentLoadVars.theContent;
}
else
{
slidingSvityk_mc.description_ta.text = "err!";
}
};
function loadQuestionData(sectionID){
var tablename ='questionsgeo'; // database tablename
//sending variables to the PHP script
questionContentLoadVars.row = sectionID;
questionContentLoadVars.tablename = tablename;
questionContentLoadVars.id_ = "";
questionContentLoadVars.img1 = "";
questionContentLoadVars.sendAndLoad("getQuestionRec.php",questionContentLoadVars,"_POST");
};
function showLoadedGalleryImages():Void{
infphp.text = questionContentLoadVars.img1;
var img1Bulk:MovieClip = new MovieClip();
img1Bulk = imgGalleryContainer_mc.img1Bulck_mc.createEmptyMovieClip(img1Bulk, _root.getNextHighestDepth());
img1Bulk._x = 0;
img1Bulk._y = 0;
image_mcl.loadClip(questionContentLoadVars.img1, img1Bulk);
};
//* And here is Flex part of embedded SWFLOader(gameplay22.swf) component
<s:SWFLoader includeIn="user" width="1024" height="768" horizontalCenter="0" source="gameplay22.swf" verticalCenter="0"/>

Related

ASP.NET Deployment issue saving image to database

I am having an unusual issue when I deploy my code from VS2015 to IIS. In VS when I run the web code, either as debug or release, the image I select and load then convert to base64 is converted to a byte array and saved to the database without any problems. However, when I deploy to the web server the code fails to work and the image is never updated. I am not getting any error information. As long as I run it from VS it all works. Is there something on the IIS server that needs to be configured? Any help or comments will be greatly appreciated.
HTML CODE
<form class="input-group" id="img2b64">
<input id="inputFileToLoad" name="files" type="file"
onchange="encodeImageFileAsURL();" />
</form>
<!-- is used to display b64 code and hold the b64 for ajax call to controller -->
<textarea id="b64" class="form-control"></textarea>
JQUERY CODE
function encodeImageFileAsURL(cb) {
return function () {
var file = this.files[0];
var reader = new FileReader();
reader.onloadend = function () {
cb(reader.result);
}
reader.readAsDataURL(file);
}
}
$('#inputFileToLoad').change(encodeImageFileAsURL(function (base64Img) {
$('#act_Photo').attr('src', base64Img);
$('#b64').val(base64Img);
}));
IN THE CONTROLLER CODE
// model.ImageFile is the base64 string
if (!string.IsNullOrEmpty(model.ImageFile))
{
// strip out base64 header
int pos = model.ImageFile.LastIndexOf(',') + 1;
string data = model.ImageFile.Substring(pos);
// get byte array of base64 image
byte[] bytes = Convert.FromBase64String(data);
// convert and save as byte array to DB
var acctImg = new WebImage(bytes).Resize(220, 200, false, true);
// aRec.Photo is in DB record
aRec.Photo = acctImg.GetBytes();
}
Seems like all is well. I restarted the site in IIS. Seems to have been a caching issue causing all the grief. Sometimes I just hate caching.

Creating MXML components via an ActionScript loop in Flex

I'm using Flash Builder 4.6 to create an app for a uni project. I have a custom Spark component, and I need to dynamically create a number of instances of that component at runtime depending on the number of XML elements returned via a PHP script.
That might be a bit confusing, so let me write the steps:
1) The application sends an HTTPService request to a PHP script hosted on the server.
2) The PHP accesses the SQL database and returns a series of XML data.
3) The ActionScript dynamically creates X instances of my custom Flex component, where X is the number of data in the XML.
Here's the code I've got so far (untidy because I'm trying to make it work):
ActionScript:
[Bindable]
public var holderArray:Array = new Array(100);
public function createMenu(e:MouseEvent):void {
var count:int = 0;
var curMenuItem:menuItemContainer = new menuItemContainer();
while (count < loadedMenu.length){
curMenuItem.itemName = loadedMenu.getItemAt(count).name;
curMenuItem.itemDesc = loadedMenu.getItemAt(count).description;
curMenuItem.itemPrice = numForm.format(loadedMenu.getItemAt(count).price);
curMenuItem.imageFile = loadedMenu.getItemAt(count).url;
//curMenuItem.y = count * 120
//menuItemGroup.addElement(curMenuItem);
holderArray[count] = curMenuItem;
count ++;
}
//testString = holderArray[1].itemName;
var count2:int = 0;
for each (var menuItem:menuItemContainer in holderArray){
menuItem.name = "menuItem" + count2;
menuItem.id = "menuItem" + count2;
//testString += menuItem.name;
menuItemGroup.addElement(menuItem);
count2++;
}
}
MXML:
<s:VGroup id="menuItemGroup" x="40" y="150">
</s:VGroup>
What seems to be happening with that code is that each of my three XML data that get returned are being used in instances of menuItemContainer, but when each one is added to menuItemGroup, it's overwriting the one that's already there. I'm not sure if the item is actually getting overwritten, or if the new item is just sitting atop the earlier ones, but if the latter is true I can't find a way to arrange the components. I've tried setting menuItem.y in the loop (as a function of count2), but to no avail.
Thanks in advance for any and all suggestions/answers.
Benjamin.
Put this line
var curMenuItem:menuItemContainer = new menuItemContainer();
inside your while loop. With your code as it is you are only creating one instance of menuItemContainer then continually changing the properties of that one menuItemContainer in your while loop. Instead you need to create a new, different instance of menuItemContainer with each iteration of the loop.

EAFlashUpload with ASP.NET 4.0 failes in Firefox, Chrome but works in IE

I'm using EAFlashUpload component with ASP.NET 4.0 on my site to allow for multiple file uploads (select multiple files at a time).
The component works great and with no issues with IE (7, 8, 9), but with Firefox or Chrome, it gives an "unknown http error" after a file is uploaded (when it is trying to do postback to the server, I think).
I'm running this under IIS7 on Windows 2008 Server R2, but I don't think the version of IIS or Windows is the significant factor.
This is the client side Javascript to handle the component:
<script type="text/javascript">
var params = { BGcolor: "#ffffff", wmode: "window" };
var attributes = { id: "EAFlashUpload", name: "EAFlashUpload" };
var flashvars = new Object();
var uploadUrl = "Pages/SendAdvanced.aspx";
//if (!document.all) {
// uploadUrl = "../" + uploadUrl;
//}
flashvars["uploader.uploadUrl"] = uploadUrl;
flashvars["viewFile"] = "EAFUpload/TableView.swf";
flashvars["view.removeButton.visible"] = "false";
flashvars["view.clearButton.visible"] = "false";
flashvars["queue.filesCountLimit"] = "10";
flashvars["queue.fileSizeLimit"] = "2147483648"; // 2 gigabytes = 2147483648 bytes
swfobject.embedSWF("EAFUpload/EAFUpload.swf", "EAFlashUpload_holder", "650", "380", "10.0.0", "EAFUpload/expressInstall.swf", flashvars, params, attributes);
function EAFlashUpload_onMovieLoad(errors) { if (errors != "") alert(errors); }
</script>
EDIT:
I discovered after further testing that the Flash component is throwing error #2038, which is a generic catchall error for "cannot connect to the server". Not sure why this is an issue with Chrome and FF, but this warrants additional investigation...
I found the answer, and it is absolutely NOT what I was expecting.
This line of code was the issue:
var uploadUrl = "Pages/SendAdvanced.aspx";
That line is a relative path, set in client side Javascript and used by the Flash component to know where to post the content.
When I changed it to this, it worked:
var uploadUrl = "http://www.mysite.com/Pages/SendAdvanced.aspx";
What I would love for someone to tell me is WHY the first line of code EVER works? Why does it work in Internet Explorer? Is there something special it is able to do to track relative paths, that the other browsers (and the Mac) won't do?
I found this answer when I was experiencing similar issues with the flash uploader (the uploads would fail before even connecting to the server). Using the following example code:
var uploadUrl = location.href;
if (!document.all) {
uploadUrl = "../" + uploadUrl;
}
//alert(uploadUrl);
var flashvars = new Object();
flashvars["uploader.uploadUrl"] = uploadUrl;
...
Turns out the problem only occurred with URLs that had a & and/or # in them (the flash object was receiving these and not knowing what to do with them because they were not encoded). There are more characters than these to worry about, however, in my case, this ended up solving the issue
I simply replaced the ampersands with the encoded version that flash was expecting, and removed the hash pound and everything following it (because it is useless from a server's perspective).
uploadUrl = uploadUrl.replace(/\&/g, '%26');
uploadUrl = uploadUrl.replace(/#.*/g, '');

Downloading data posted to server as a file from Flex

This should be trivial, and I'm pretty sure I did it once before.
I'm trying to post data up to a server and have it bounced back to me as a file download, prompting the native browser file download box. I know the server part works just fine becasue I can post from a demo web form, but when I run the following Flex 3 code, I can't even get the request to fire.
var fileRef:FileReference = new FileReference();
private function saveXmlAsFile(event:MouseEvent):void
{
var fileRequest:URLRequest = new URLRequest();
fileRequest.method = URLRequestMethod.POST;
fileRequest.url = "http://foo.com/dataBounce";
var urlVariables:URLVariables = new URLVariables();
urlVariables.content = "Test content to return" ;
// fileRequest.contentType = "application/x-www-form-urlencoded ";
urlVariables.fileName = "test.xml";
fileRef.addEventListener(SecurityEvent.ALL, onSecurityError);
fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError2);
fileRef.addEventListener(IOErrorEvent.NETWORK_ERROR, onNetworkError);
fileRef.addEventListener(Event.COMPLETE, onComplete);
try
{
fileRef.download(fileRequest, "test.xml");
}catch(error:Error) {
model.logger.error("unable to download file");
}
}
Note, when the call to fileRef.download is called, I can't see any request being made across the network using the traditional Firebug or HTTPWatch browser tools.
EDIT: I should add that this is for < Flash Player 10, so I can't use the newer direct save as file functionality.
Any suggestions? Thanks.
You need to add fileRef.upload to trigger the upload.
Also I would move the download statement to the onComplete so the file isn't requested before it's been uploaded.
Your explanation is pretty clear, but when I look at your code, I'm feel like I'm missing something.
The code looks like you're trying to do half of the upload part and half of the download part.
I think the code you currently have posted would work to trigger a download if you set the .method value to GET. I believe you will also need to include the filename as part of the .url property.
However, to post something and then trigger a download of it, you need two separate operations - the operation to post the data and then an operation to download it, which should probably be called from the upload operation's onComplete handler.
OK, I believe I figured out one of the things that's going on.
When you don't set the URLRequest.data property, it defaults the request method to "GET".
So, the working code looks like, with the data set to the posted URL variables:
private var fileRef:FileReference;
private function saveRawHierarchy(event:MouseEvent):void
{
var fileRequest:URLRequest = new URLRequest();
fileRequest.method = URLRequestMethod.POST;
fileRequest.url = "http://foo/bounceback";
var urlVariables:URLVariables = new URLVariables();
urlVariables.content = "CONTENT HERE";
urlVariables.fileName = "newFileName.xml";
fileRequest.data = urlVariables;
fileRef = new FileReference();
fileRef.addEventListener(Event.COMPLETE, onComplete);
try
{
fileRef.download(fileRequest, "appHierarchies.xml");
}catch(error:Error) {
model.logger.error("unable to download file");
}
}
Not sure what was wrong about the request not being made before, though.

Flex 3 - how to support HTTP Authentication URLRequest?

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.

Resources