I want to upload some files to my server with a drag'n'drop angularjs directive. I've hardcoded for hours but I haven't still found the error. I have that angularjs code:
var fd = new FormData();
for(x = 0; x < files.length; x++)
fd.append("file[]", files[x]);
fd.append('type', 'upload');
xhr = new XMLHttpRequest();
xhr.open("post", "/../RESOURCES/API/explorer.php", true);
xhr.upload.addEventListener("progress", function(e) {
var pc = parseInt(100 - (e.loaded / e.total * 100));
console.log(pc);
}, false);
xhr.onload = function() {
console.log(xhr.responseText);
};
xhr.send(fd);
But my APIs returns empty $_POST and $_FILES. Thanks!
With Angular JS, I've achieved file upload with the following code:
angular.module('frApp')
.service('fileUpload', ['$http',function ($http) {
this.uploadFileToUrl = function(file, uploadUrl, success, error){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).success(success)
.error(error);
};
}]);
Related
I want to show a pdf file from a GET request on a HTML page using plain Java Script.
The api returns a pdf-file.
This is the postman response of the api:
Here is my code so far:
function getImg() {
var url = "https://api.herokuapp.com/download"
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader("Authorization", "JWT " + localStorage.getItem('token'));
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(null);
xhr.addEventListener('load', function() {
var responseObject = this.response;
var myImage = new Image();
myImage = this.response;
document.body.appendChild(myImage);
});
}
I get this error:
TypeError: Argument 1 of Node.appendChild is not an object.
How can this be done?
Any help is very appreciated.
BR KRESTEN
Here is how I solve this:
function getImg() {
var url = "https://secure.gravatar.com/avatar/3167fa1b890ffe735393de7d6296e32d?s=58&d=mm&r=g"
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
// xhr.setRequestHeader("Authorization", "JWT " + localStorage.getItem('token'));
// xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(null);
xhr.addEventListener('load', function() {
if (this.status === 200) {
let blob = this.response;
let myImage = new Image();
myImage.src = window.URL.createObjectURL(blob);
document.body.appendChild(myImage);
}
});
}
I have a method in JavaScript to read from a binary file into an ArrayBuffer and send it to a Jersey POST method:
function readAndSendBytes() {
var file = document.getElementById("entityFileField").files[0],
reader = new FileReader();
var entityBytes = reader.readAsArrayBuffer(file);
reader.onloadend = function () {
alert(reader.result);
}
var xhr = new XMLHttpRequest();
var url = "/api/upload/e2j";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.responseType = "json";
xhr.onload = function (e) {
var response = xhr.response;
alert(response);
}
xhr.send(reader.result);
}
Jersey:
#Path("/upload")
public class ParserHandler {
#POST
#Path("/e2j")
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
#Produces(MediaType.APPLICATION_JSON)
public String entityToJsonTwoElectricBoogaloo(byte[] entityPayload) {
System.out.println(entityPayload.length);
}
Whenever I print length to the console, the length is always 0, when it should be 439. What am I doing wrong?
there is no need to use the filereader, you can just send the blob with xhr
function sendFile() {
var file = document.getElementById("entityFileField").files[0];
var xhr = new XMLHttpRequest();
var url = "/api/upload/e2j";
xhr.open("POST", url);
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.responseType = "json";
xhr.onload = function (e) {
var response = xhr.response;
alert(response);
}
xhr.send(file);
}
Found the solution! Just moved everything but send and initialisations of file and FileReader into the xhr.onload function!
EDIT: Forgot to post my solution.
function postEntity() {
var output = document.getElementById("response");
var file = document.getElementById("entityFileField").files[0];
var jsonResponse;
var r = new FileReader();
r.onloadend = function(e) {
var data = r.result;
var xhr = new XMLHttpRequest();
var url = "/api/upload/entitytojson";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.responseType = "json";
xhr.onload = function (e) {
if (xhr.response != null) {
jsonResponse = JSON.stringify(xhr.response);
output.innerHTML = jsonResponse;
}
else {
alert("Invalid Entity File");
}
}
xhr.send(data);
}
r.readAsBinaryString(file);
}
I'm trying to use the angular upload library to upload a file and see the percentage of uploading. The method itself works well and the file can be uploaded on my server but when i try to see the percentage it shows me this
progress: 6%
progress: 100%
or anyway it shows only the first percentage, in this case 6% but could be 40% or something else, and then directly 100%. This is the code
$scope.uploadFileFunction = function(file) {
var uploadUrl = "url";
var newJson;
var json = [];
json.push(newJson);
var self = this;
self.loading = true;
var fd = new FormData();
if (file != undefined && file != null) {
fd.append('file', file);
}
fd.append('json', angular.toJson(json));
Upload.http({
url: uploadUrl,
transformRequest: angular.identity,
method: 'POST',
headers: {
'Content-Type': undefined
},
data: fd
}).then(function (data, status) {
self.loading = false;
$scope.uploadError = false;
}, function (resp) {
self.loading = false;
$scope.uploadError = true;
}, function (evt) {
$scope.upPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + $scope.upPercentage + '% ');
});
};
is it normal? It happens also if i upload large files. This is the link to the library i'm using https://github.com/danialfarid/ng-file-upload
I am trying to use the facebook api to upload an image from a canvas I save on the page:
var file = dataURItoBlob(canvas.toDataURL('image/jpeg', 1.0))
FB.api('/me/photos', 'POST', {
source: file,
message: 'photo description'
}, function (response) {
console.log(response)
}
)
This is the blob convertor:
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: 'image/jpeg' });
}
And I am getting an error: message: "(#324) Requires upload file" so it seems the uploader does not recognize the blob as a valid file.
UPDATE 1:
I fount this post: Convert Data URI to File then append to FormData about converting blob to formData, tried it like this:
var dataURL = canvas.toDataURL('image/jpeg', 1.0)
var blob = dataURItoBlob(dataURL)
var fd = new FormData(document.forms[0])
fd.append("canvasImage", blob)
FB.api('/me/photos', 'POST', {
source: fd .....
But still the same error.
UPDATE 2:
Even tried this XHR post solution, Using Facebooks javascript api to post multipart/form-data encoded image and still getting file issue "Your photos couldn't be uploaded. Photos should be less than 4 MB and saved as JPG, PNG, GIF or TIFF files."
function postImageToFacebook(access_token) {
var filename = "samplepic.png",
mimeType = "image/png",
message = "test comment",
data = canvas.toDataURL("image/png"),
encodedPng = data.substring(data.indexOf(',') + 1, data.length),
imageData = atob(encodedPng);
// build the multipart/form-data
var boundary = '----ThisIsTheBoundary1234567890';
var formData = '--' + boundary + '\r\n'
formData += 'Content-Disposition: form-data; name="source"; filename="' + filename + '"\r\n';
formData += 'Content-Type: ' + mimeType + '\r\n\r\n';
for (var i = 0; i < imageData.length; ++i) {
formData += String.fromCharCode(imageData[i] & 0xff);
}
formData += '\r\n';
formData += '--' + boundary + '\r\n';
formData += 'Content-Disposition: form-data; name="message"\r\n\r\n';
formData += message + '\r\n'
formData += '--' + boundary + '--\r\n';
var xhr = new XMLHttpRequest();
xhr.open( 'POST', 'https://graph.facebook.com/v2.5/me/photos?access_token=' + access_token, true );
xhr.onload = xhr.onerror = function() {
console.log( xhr.responseText );
};
xhr.setRequestHeader( "Content-Type", "multipart/form-data; boundary=" + boundary );
xhr.send( formData );
}
I figured out, for some reason, the issues was the headers that I tried to apply as a solution for a previous problem... Here is a working solution: https://jsfiddle.net/ilyador/vyne7oh2/8/
function fbUpload(token){
var dataURL = canvas.toDataURL('image/jpeg', 1.0)
var blob = dataURItoBlob(dataURL)
var formData = new FormData()
formData.append('token', token)
formData.append('source', blob)
var xhr = new XMLHttpRequest();
xhr.open( 'POST', 'https://graph.facebook.com/me/photos', true )
xhr.onload = xhr.onerror = function() {
console.log( xhr.responseText )
};
xhr.send( formData )
}
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); }
return new Blob([ab], { type: 'image/jpeg' });
}
To upload directly from canvas to Facebook photos, this works for me:
function postImageToFacebook(token, imageData, message, successCallback, errorCallback) {
var fd = new FormData();
fd.append("access_token", token);
fd.append("source", imageData);
fd.append("caption", message);
$.ajax({
url: "https://graph.facebook.com/me/photos?access_token=" + token,
type: "POST",
data: fd,
processData: false,
contentType: false,
cache: false,
success: function (data) {
successCallback(data);
},
error: function (shr, status, data) {
errorCallback(data);
},
complete: function (data) {
console.log('Completed');
}
});
}
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: 'image/jpeg'});
}
To use it
// *IMPORTANT*
var FBLoginScope = 'publish_actions'; // or sth like 'user_photos,publish_actions' if you also use other scopes.
var caption = "Hello Facebook!";
var successCallback = ...;
var errorCallback = ...;
var data = $('#your_canvas_id')[0].toDataURL("image/jpeg");
try {
imageData = dataURItoBlob(data);
} catch (e) {
console.log(e);
}
FB.getLoginStatus(function (response) {
if (response.status === "connected") {
postImageToFacebook(response.authResponse.accessToken, imageData, caption, successCallback, errorCallback);
} else if (response.status === "not_authorized") {
FB.login(function (response) {
postImageToFacebook(response.authResponse.accessToken, imageData, caption, successCallback, errorCallback);
}, {scope: FBLoginScope});
} else {
FB.login(function (response) {
postImageToFacebook(response.authResponse.accessToken, imageData, caption, successCallback, errorCallback);
}, {scope: FBLoginScope});
}
});
Modified from: http://gorigins.com/posting-a-canvas-image-to-facebook-and-twitter/
I'm using this tool to crop images in my AngularJS app: https://github.com/fengyuanchen/cropper
and then I try to store data to server, but now I send base64 code... How could I send normal cropped image binary code, not as base64? is it real?
my code for uploading is such:
var addImage = function(files) {
var deferred = $q.defer();
var fd = new FormData();
var blob = new Blob([files], { type : "image/png"});
fd.append("file", blob);
$http.post(settings.apiBaseUri + "/files", fd, {
withCredentials: true,
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity
})
.success(function(data, status, headers, config) {
url = data.Url;
deferred.resolve(url);
})
.error(function(err, status) {
});
return deferred.promise;
};
and here I send base64 code:
$scope.photoChanged = function(files) {
$scope.oldImg = angular.element(document.querySelector('#avatar-id'));
$scope.files = files;
var reader = new FileReader();
reader.onload = function(e) {
$scope.imagecontent = e.target.result;
};
reader.readAsDataURL(files[0]);
};
and
$scope.setCroppedData = function(data) {
$('#avatar-id').attr('src', data);
$scope.nImg = new Image();
$scope.nImg.src = data; // data - is base64 image code
}
...
uploaderService.addImage($scope.nImg.src).then(function(url) {
$scope.person.AvatarUrl = url;
$scope.updateContactQuery();
});
...
how could I send like I do without any croping: send image file, so that i could go via link in browser and see image, but not a byte64 code???
You can wrap the base64 data in ArrayBuffer then convert to binary Image data like:
var binaryImg = atob(base64Image);
var length = binaryImg.length;
var arrayBuffer = new ArrayBuffer(length);
var uintArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < length; i++) {
uintArray[i] = binaryImg.charCodeAt(i);
}
I suppose uintArray is what you want.