I am trying to POST an image to my grails application and I'm not having much luck.
My titanium code is:
function upload(){
var xhr = Titanium.Network.createHTTPClient();
xhr.onerror = function(e){
Ti.API.info(picMedia + " : " +message.value);
Ti.API.info('IN ERROR ' + e.error);
alert('Sorry, we could not upload your photo! Please try again.');
};
xhr.onload = function(){
Ti.API.info('IN ONLOAD ' + this.status + ' readyState ' + this.readyState);
};
xhr.onsendstream = function(e){
Ti.API.info('ONSENDSTREAM - PROGRESS: ' + e.progress);
};
// open the client
xhr.open('POST', 'http://localhost:8080/FYP/Profile/appUploader');
// send the data
xhr.send({
media: picMedia,
message: message.value,
});
}
My grails code is as follows:
def appUploader(){
println "MEDAI PARAMS: " + params.media
def f = request.getFile('media') ;
println "HERE: " + f
if (request.getFile(params.media).getOriginalFilename()) {
println "FROM APP: " + request.getFile('myFile').getOriginalFilename()
return
}
}
Im getting error from the mobile app and error on the "if" line in the web app.
What am i doing wrong?
we had the same problem in one of our apps. The difficulty is that titanium is not really able to handle binary files in that case.
We did the following:
create base64 encoded string of the image on client side
post this string to the backend
decode base64 to image again
We analyzed a lot of network traffic and in most cases titanium tries to send the file but due to javascript its alway converted into some kind of ascii and this is not usable by the server side.
Related
Wracking my brain for quite some time on this - thought I'd ask the experts for an assist...
The gist of my code below is to call a php function (via ajax POST) that updates a MySQL table when a registration request is rejected by an administrator.
When executing in Windows 10, all works as expected. But on iOS, it throws the error alert found in the .fail function of the ajax call (alert("A problem has occurred with your rejection at tec_regadmin. " + teststat2 + " Please copy this error and contact your abc administrator for details.");). Also, teststat2 is displayed as [object Object] on iOS.
An additional twist - the MySQL table successfully UPDATEs to show that the request was rejected. Code snippets are below:
JS function with embedded ajax call to ../services/ajax_reject_registrant.php:
function regreject(Select, Directory_ID, Log_In, Gender_sex, First_Name, Last_Name) {
console.log("Made it into the regreject function");
var jQ13 = jQuery.noConflict();
jQ13(document).ready(function () {
jQ13.ajax({
cache: false,
headers: { "cache-control": "no-cache" },
url: '../services/ajax_reject_registrant.php',
type: 'POST',
dataType: 'json',
data: { Selected: Select, Directory: Directory_ID, Login: Log_In, Gender: Gender_sex, FirstName: First_Name, LastName: Last_Name }
})
.done(function (jqXHR, textStatus) {
// Get the result
var teststat = textStatus;
var teststat2 = jqXHR;
console.log("ajax reject success response data = " + teststat);
console.log("ajax reject success response text = " + teststat2);
alert("Registrant has been disabled in the database.");
location.reload();
return;
})
.fail(function (jqXHR, textStatus) {
// Get the result
var teststat = textStatus;
var teststat2 = jqXHR;
console.log("ajax reject failure response data = " + teststat);
console.log("ajax reject failure response text = " + teststat2);
alert("A problem has occurred with your rejection at tec_regadmin. " + teststat2 + " Please copy this error and contact your abc administrator for details.");
location.reload();
return;
});
});
};
PHP script (../services/ajax_reject_registrant.php) called from ajax:
<?php
//New Registrant Reject script
//Called from tec_regadmin.php
//Last Updated 2020/12/09
if ( isset($_POST['Selected']) ) {
require('../tec_dbconnect.php');
include('../includes/event_logs_update.php');
include('tec_sendmail.php');
$Selected2 = $_POST['Selected'];
$Directory2 = $_POST['Directory'];
$Login2 = $_POST['Login'];
$Gender2 = $_POST['Gender'];
$FirstName2 = $_POST['FirstName'];
$LastName2 = $_POST['LastName'];
$text = array();
$regrejectloginquery = "UPDATE " . $_SESSION['logintablename'] . " SET active = '2'" . " WHERE login_ID = '". $Login2 . "'";
$regrejectlogin = $mysql->query($regrejectloginquery) or die("A database error occurred when trying to reject new Registrant info into Login table. See ajax_reject_registrant.php. Error:" . $mysql->errno . " : " . $mysql->error);
eventLogUpdate('admin_update', "Admin ID: " . $_SESSION['user_id'], "Registrant Reject", "LoginID: " . $Login2 . " - Directory entry: " . $Directory2);
$success = 'Reject Success';
header('Content-type: application/json');
echo json_encode($success);
}
else{
$failed = 'Reject Failed';
header('Content-type: application/json');
echo json_encode($failed);
}
?>
Let me know if you have any questions. Any suggestions would be GREAT!
Thank you!!!
[SOLVED]
A PHP form is used to call the above function (regreject) and was missing an action statement (was displayed as action=''). By modifying the action to include javascript:void(0); the issue resolved itself. All I needed to do was change the action to action="javascript:void(0);" in the original PHP form, and now iOS is a happy camper!
The final question I will have to ponder is "WHY was this a problem with iOS??" Wonder if I'll ever find out.
I'm trying to open an already present .pdf file on iOS [I can see the files in iBooks].
I use Ionic and the file-opener2 Cordova plugin - I use the latest versions of Cordova and the plugin.
This is the code that works perfectly on Android:
$scope.openPDF = function() {
alert("OK");
$cordovaFileOpener2.open(
'/storage/emulated/0/Download/pdf/name.pdf', // Any system location, you CAN'T use your appliaction assets folder
'application/pdf'
).then(function() {
console.log('Success');
}, function(err) {
console.log('An error occurred: ' + JSON.stringify(err));
});
};
Yes, I want to be a local file without having to download it, this is a show off app that won't have internet connection where will be running for just one day. So the files have to be local.
I have no idea how to open the file paths like in Android. Running on iOS 9.3.3., iPad Pro. Also, the device is not jail-broken.
Edit:
Well, now I'm trying to move the files from the app's folder to another one, so I can open it from there. Again, all of the code works on Android.
function openPDF(uri) {
var filePath = cordova.file.applicationDirectory + 'www/pdf/fichas/name.pdf';
alert(filePath);
window.resolveLocalFileSystemURL(filePath, function(entry) {
var fileTransfer = new FileTransfer();
var targetFile = cordova.file.externalDataDirectory + entry.name;
fileTransfer.download(
entry.toURL(),
targetFile,
function(entry) {
console.log("download complete: " + entry.toURL());
console.log("targetFile: " + targetFile);
cordova.plugins.fileOpener2.open(
targetFile,
'application/pdf',
{
error : function(error){ alert('open error ' + JSON.stringify(error)) },
success : function(){ }
}
);
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
}
);
}, function(error){ alert('error resolveLocalFileSystemURI ' + JSON.stringify(error)) });
};
alert(filePath); * returns: file:///var/containers/Bundle/Application/xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx/NAME.app/www/pdf/name.pdf
I don't know where it fails though. I won't open anything.
edit2:
I get a FileTransfer error indeed. "
Could not create path to save dowloaded file.
I'm working on uploading image as base64 image stream from phonegap/cordova application, it works perfectly fine in Android but not working in ios, however in ios it works when the image is as png/jpg but when it is as base64 image stream its not working, Please can anybody help me out with the same.
Here is my code for the same,
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = "test.jpg";
options.mimeType = "image/jpeg";
options.chunkedMode = false;
options.params = {
"key": "test.jpg",
"AWSAccessKeyId": awsKey,
"acl": acl,
"policy": policyBase64,
"signature": signature,
"Content-Type": ""
};
var ft = new FileTransfer();
ft.upload(imageURI, s3URI + "",
win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
alert(r.response);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
}
Version 1.5.0 of the file transfer plugin has already added that functionality. The patch was applied 14 Dec 2015.
You can see the commit here.
Upgrading the plugin solved the problem in my case at least.
Set chunkMode true when use base64 for upload using phonegap
I set chunkMode true but still file is not transferring on server .It seems that cordova file transfer plugin does not support base64 image for upload on iOS.
first, sorry if my english is bad.
Then, here is my issue:
I try to make an app for iOS with PhoneGap 2.8.1 . Evrything is going well on Android, now I just want to move my code on Xcode to compile on iPad or iPhone.
The probleme I have is with FileTransfer, when I upload an image. The transfer itself has no problem, as it finishes with a response code 200, so it's a success.
Then, my serve is supposed to return back an XML file, handled by the javascript code. The server works fine, because I have absolutly no problem with Android devices.
So, I made a lot of tests, and it appears that the app has a problem with the success callback or the FileTransfer.upload(). When I just put a simple console.log('success') in this callback function, it's fine. But when I try to use the FileUploadResult object, nothing happens.
And the weirdest thing is, that when I press the main button of the iPad or iPhone, in order to close my app, I see all my logs displayed in the debug window, such as console.log("Code = " + r.responseCode);, like in the PhoneGap example. And here, I can finally see that I actually receive the server response, but it's like something blocks it until I close the app.
Here is that part of the code :
function onPhotoDataSuccess(imageURI) {
console.log("---> Image: "+imageURI);
// File Transfer
var options = new FileUploadOptions();
options.fileKey="file";
options.chunkedMode = false;
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI(window.localStorage.getItem("wsURL")), win, fail, options);
// Transfer succeeded
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
// Handle the XML response
}
else {
alert("No response. Please retry");
}
}
// Transfer failed
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
}
Thanks for your help
Is there any way to send Ajax requests to server from a Firefox plugin? If yes, how? If no, how do we have client server communication in Firefox plugins?
I want to get some JSON data from server and manipulate the DOM object according to the client input.
I am pretty a beginner in plugin programming.
You can send ajax requests from firefox extension using xmlHTTPRequest, like in any other web application.
From a contentscript you should add the permissions to access cross-domain content, URLs you want to:
"permissions": {
"cross-domain-content": ["http://example.org/", "http://example.com/"]
}
More info in the documentation.
Here's a simple snippet that does XHR request, WITHOUT cookies (due to flag Ci.nsIRequest.LOAD_ANONYMOUS can remove to send with cookies) (MDN :: Info on flags]. Copy this first code block in, then see usage examples below.
var {Cu: utils, Cc: classes, Ci: instances} = Components;
Cu.import('resource://gre/modules/Services.jsm');
function xhrGetPost(url, post_data, cb) {
let xhr = Cc["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
let handler = ev => {
evf(m => xhr.removeEventListener(m, handler, !1));
switch (ev.type) {
case 'load':
if (xhr.status == 200) {
cb(xhr.response);
break;
}
default:
Services.prompt.alert(null, 'XHR Error', 'Error Fetching Package: ' + xhr.statusText + ' [' + ev.type + ':' + xhr.status + ']');
break;
}
};
let evf = f => ['load', 'error', 'abort'].forEach(f);
evf(m => xhr.addEventListener(m, handler, false));
xhr.mozBackgroundRequest = true;
if (post_data == undefined) {
post_data = null;
}
if (post_data) {
xhr.open('POST', url, true);
} else {
xhr.open('GET', url, true);
}
xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS | Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING;
//xhr.responseType = "arraybuffer"; //dont set it, so it returns string, you dont want arraybuffer. you only want this if your url is to a zip file or some file you want to download and make a nsIArrayBufferInputStream out of it or something
xhr.send(post_data);
}
Example usage of for POST:
var href = 'http://www.bing.com/'
xhrGetPost(href, 'post_data1=blah&post_data2=blah_blah', data => {
Services.prompt.alert(null, 'XHR Success', data);
});
Example usage of for GET:
var href = 'http://www.bing.com/'
xhrGetPost(href, null, data => {
Services.prompt.alert(null, 'XHR Success', data);
});