The application I'm working uses an API developed by another team. I'm working on Titanium 2.1.2 and I'm trying to upload a photo using said API. I'm using Appcelerator's HTTPClient to make the request. Here's my code:
var url = 'http://api.veramiko.com/albums/' + album.veramiko_id + '/photos';
var photo = imageView.toBlob();
var args = { //parameters sent to post photo
file : photo,
description : descriptionText
};
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info(this.responseText); //Print the result
},
onerror : function(e){
Ti.API.error(this.responseText); //Print the result
},
timeout : 60000
});
client.open('POST', url);
client.setRequestHeader('Authorization', 'Bearer ' + token);
client.setRequestHeader('Content-type', "multipart/form-data");
client.send(args);
Token is a variable we use to authorize any requests made to the server. I thought that by only converting the image from the ImageView into Blob would be enough to send the photo, but the photo isn't uploaded. The post is created with the description but the photo isn't sent properly.
Do I need to add something else? Is it right to send the photo as a Blob?
EDIT: I read this link and I tried the following with no result:
var url = 'http://api.veramiko.com/albums/' + album.veramiko_id + '/photos';
var boundary = '-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var photo = imageView.toBlob();
var args = {
file : photo,
description : descriptionText.value
};
var contentDisposition = "--" + boundary + "\r\n";
contentDisposition += "Content-Disposition: form-data; name=\"file\";";
contentDisposition += "filename=\"" + imageView.image + "\"\r\n\";";
contentDisposition += "Content-Type: application/octet-stream\r\n\r\n";
var fullContent = contentDisposition + photo + "\r\n--" + boundary + "--";
alert(JSON.stringify(args));
var token = JSON.parse(Ti.App.Properties.getString('loggedUser', 'No existe')).networks[0].token;
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info(this.responseText); //Print the result
},
onerror : function(e){
Ti.API.error(this.responseText); //Print the result
},
timeout : 60000
});
client.open('POST', url);
client.setRequestHeader('Authorization', 'Bearer ' + token);
client.setRequestHeader('Content-Type', "multipart/form-data; boundary=\"" + boundary + "\"");
client.setRequestHeader('Connection', 'close');
client.send(fullContent);
I tried to wrap the file with a Content-Disposition and Content-Type header with no result.
I finally found a way to solve this. Please refer to the following link.
This is how my code looked in the end:
// I put the contents of my image into a variable
var f = imageHolder.toImage();
// I create a random name for the image
var tmpName = (new Date()).getTime().toString() + '.png';
// I create a folder where I will store the photo temporally
var g = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'picturesToUpload');
if (!g.exists()) {
// If the directory doesn't exist, make it
g.createDirectory();
};
var photo = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'picturesToUpload', tmpName);
// write the contents of the image into the file
photo.write(f);
// I create my url with the albumId where I'll upload the picture
var url = 'http://api.veramiko.com/albums/' + albumId + '/photos';
var args = {
file : photo.read(), // I read the contents of the file
description : ''
}
var token = JSON.parse(Ti.App.Properties.getString('loggedUser', 'No existe')).networks[0].token;
var client = Ti.Network.createHTTPClient({
onload : function(e){
Ti.API.info('Info received from the uploading: ' + this.responseText);
},
onerror : function(e){
Ti.API.debug('Error: ' + this.responseText);
},
timeout : 60000
});
client.open('POST', url);
// these headers are important
client.setRequestHeader('enctype', 'multipart/form-data');
client.setRequestHeader('Content-Type', 'image/png');
client.setRequestHeader('Authorization', 'Bearer ' + token);
client.send(args);
Hope this info helps more people.