I'm developing a set of tools in JavaScript and I'm having a trouble with saving static images. First of all I've created uploader to upload images that are later saved in upload/ directory.
Uploaded images (file) are sent to server like this:
$.ajax({
data: { file: e.dataTransfer.file },
url: 'server/uploading_files.php',
method: 'POST',
success: function (response) {
....
}
});
And I would love to do the same with images where I have only path to them -> statically save them.
Problem is in structure I'm sending to server side. Because e.dataTransfer.file looks like this:
FileList{0: File, length: 1}
0: File
lastModified:1441797733000
lastModifiedDate:Wed Sep 09 2015 13:22:13 GMT+0200 (CEST)
name:"sp_dom1.jpg"
size:563989
type:"image/jpeg"
webkitRelativePath:""
And when I want to save static image I have only path without any structure.
Is there any solution how to crate the same structure for uploading static images? I don't want to use 2 different .php files for save.
You can utilize XMLHttpRequest, with responseType set to "blob", new File() constructor available at chrome / chromium 38+
var dfd = new $.Deferred();
var pathToImage = "http://lorempixel.com/50/50/";
var request = new XMLHttpRequest();
request.responseType = "blob";
request.open("GET", pathToImage);
request.onload = function() {
var file = this.response;
dfd.resolve(
new File([file]
, file.name
|| "img-" + new Date().getTime()
+ "." + file.type.split("/")[1]
, {
type: file.type
}
)
)
};
request.send();
dfd.then(function(data) {
// do stuff with `data`
// i.e.g.;
// $.ajax({
// data: { file: data },
// url: 'server/uploading_files.php',
// method: 'POST',
// success: function (response) {
// ....
// }
// });
console.log(data);
var img = new Image;
img.onload = function() {
$("body").append(this)
}
img.src = URL.createObjectURL(data);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
Related
I have two audio files from RecordRTC both local & remote streams. Now I want to merge the two files into one file and upload it to the server via AJAX.
e.g. (audio1.webm) and (audio2.webm).
mediaRecorder.stopRecording(function() {
var blob = mediaRecorder.getBlob();
var fileName = getFileName('webm');
var fileObject = new File([blob], fileName, {
type: 'audio/webm'
});
var formData = new FormData();
formData.append('blob', fileObject);
formData.append('filename', fileObject.name);
$.ajax({
url: '{{ url('/') }}/save-audio',
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(response) {
console.log(response);
}
});
});
Thank you in advance.
UPDATE:
I made it this way instead of recorder.addStreams, and still I can get the recorded.
var remoteVideos = $('#remoteVideos video');
var el = [];
$.each($('#remoteVideos video'), function(index, val) {
el[index] = val.srcObject;
});
el.push(stream);
multiMediaRecorder = new MultiStreamRecorder(el);
You can use a similar library: MediaStreamRecorder. Then use MultiStreamRecorder and pass two streams as below,
recorder = new MultiStreamRecorder([localStream, remoteStream]);
You will get localStream from getUserMedia and remoteStream from onaddstream event listener.
You may want to just pass the audio tracks in the array. The rest of the things as it is. FFmpeg and file merging is not necessary.
I got it now by doing this, as below;
function onMediaSuccess(localStream) {
var remoteVideos = $('#remoteVideos video')[0];
multiMediaRecorder = new MultiStreamRecorder([localStream, remoteVideos.srcObject]);
multiMediaRecorder.ondataavailable = function (blob) {
// POST/PUT "Blob" using FormData/XHR2
var blobURL = URL.createObjectURL(blob);
console.log(blobURL);
};
multiMediaRecorder.start();
}
But now there's another problem, ondataavailable is called twice but the first video is playable and working properly, while the second video is playable but (less than one second) I think it might be corrupted.
Cheers!
I am sending byte array from backend and trying to open it with ajax and JS, I am always having corrupted PDf which cannot be opened.
me code is below.
$.ajax({
responseType: 'application\pdf',
sucess: function (response)
{
var blob=new blob([response]),{type:'application\pdf'};
window.navigator.msSaveOrOpen(blob);
}
});
any help would be much appreciated. thank you
Having the same issue with IE, ajax headers fixed the problem
$.ajax({
url: this.href,
cache: false,
xhrFields: {
responseType: 'blob'
},
success: function (data) {
var newBlob = new Blob([data], { type: "application/pdf" })
navigator.msSaveOrOpenBlob(newBlob, "something.pdf");
},
error: function (error) {
console.log(error);
}
});
First, set a break point in the success function, then try to use F12 developer tools to debug your code and make sure you could get the pdf blob. Then, use the window.navigator.msSaveOrOpenBlob() method to download pdf file.
Code as below:
var req = new XMLHttpRequest();
req.open("GET", "/44678.pdf", true);
req.responseType = "blob";
req.onload = function (event) {
var blob = req.response;
var newBlob = new Blob([blob], { type: "application/pdf" })
// IE doesn't allow using a blob object directly as link href
// instead it is necessary to use msSaveOrOpenBlob
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
};
More details, you could check this article.
Edit:please check your code, the Ajax method doesn't have the request url and have a spelling mistake at the success function.
I have an Angularjs 1.5.0 web application which should communicate with a REST-based web service that I had developed (using dropwizard & jersey) and tested that it works perfectly.
The REST web service method is like this:
#POST
#Path("/saveImage")
public Response saveImage(
#FormDataParam("imagefile") InputStream uploadedInputStream,
#FormDataParam("imagefile") FormDataContentDisposition fileDetail) {
// save image on server's file system and return OK
}
Scanned images are available to me by the scanner's local web server through a link like this: http://localhost:9980/thumb/random-generated-guid.jpg
In my angularjs code, I want to send the image which is available with the link above to my REST service.
Does anybody know how to do this?
I tried first saving the image as a blob and then send it to the web service. I could save the image using javascript's XMLHttpRequest but sending always fails.
Code for saving the image as Blob:
var xhr = new XMLHttpRequest();
xhr.open('GET', imageAddress, true);
xhr.responseType = 'blob';
var imageData = null;
xhr.onload = function(e) {
if (this.readyState === 4 && this.status === 200) {
// get binary data as a response
imageData = this.response;
var gatewayResponse = sendToGateway(imageData);
}
};
Code for sending the blob data:
var sendToGateway = function(imageDataBlob) {
var formdata = new FormData();
formdata.append('imagefile', imageDataBlob)
$.ajax({
url: 'http://localhost/eval/saveImage',
method: 'POST',
contentType: 'multipart/form-data; charset=UTF-8',
data: formdata,
dataType: 'json',
})
.done(function(response) {
$log.info("**************** response = " + response);
alert("response:\n" + response);
})
.fail(function(jqXHR, textStatus, errorThrown) {
$log.error("!!!! FAIL !!!!!!!!!");
alert("FAIL !!!!!!!");
})
.always(function(){
$rootScope.scannerInactive = false;
doStartPreviewUpdate();
});
};
Actually, the problem is when the sendToGateway(imageData); is called, I get the error:
TypeError: 'append' called on an object that does not implement
interface FormData.
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" :
value );
oops, I found the problem. I should have added the following directives to the $.ajax() call.
processData: false,
contentType: false,
I am trying to upload files directly to dropbox [from a browser / web application], The "uploadFile" function on the code API needs the file to be uploaded available on the server, this puts me in trouble, because I do not want any files to be uploaded to my server and from there to dropbox.
$f = fopen("test.jpg", "rb"); // requires file on server
$result = $dbxClient->uploadFile("test.jpg", dbx\WriteMode::add(), $f);
fclose($f);
Tried out this https://github.com/dropbox/dropbox-js disappointed to say that there is no clear documentation, many of the links on the documentation part is broken.
I need the files to be uploaded to my account and the clients need not login to dropbox.
Any pointers would be really appreciated. looking for Ajax / JavaScript methods.
Update
I have tried the following, but no response from Dropbox
HTML
<input type="file" name="file" id="file" onchange="doUpload(event)">
JavaScript
var doUpload = function(event){
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var arrayBuffer = reader.result;
$.ajax({
url: "https://api-content.dropbox.com/1/files_put/auto/uploads/" + input.files[0].name,
headers: {
Authorization: 'Bearer ' + MyAccessToken,
contentLength: file.size
},
crossDomain: true,
crossOrigin: true,
type: 'PUT',
contentType: input.files[0].type,
data: arrayBuffer,
dataType: 'json',
processData: false,
success : function(result) {
$('#uploadResults').html(result);
}
});
}
reader.readAsArrayBuffer(input.files[0]);
}
Dropbox just posted a blog with instructions on how to do this. You can find it at https://blogs.dropbox.com/developers/2016/03/how-formio-uses-dropbox-as-a-file-backend-for-javascript-apps/ (Full disclosure, I wrote the blog post.)
Here is how to upload a file.
/**
* Two variables should already be set.
* dropboxToken = OAuth token received then signing in with OAuth.
* file = file object selected in the file widget.
*/
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(evt) {
var percentComplete = parseInt(100.0 * evt.loaded / evt.total);
// Upload in progress. Do something here with the percent complete.
};
xhr.onload = function() {
if (xhr.status === 200) {
var fileInfo = JSON.parse(xhr.response);
// Upload succeeded. Do something here with the file info.
}
else {
var errorMessage = xhr.response || 'Unable to upload file';
// Upload failed. Do something here with the error.
}
};
xhr.open('POST', 'https://content.dropboxapi.com/2/files/upload');
xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
path: '/' + file.name,
mode: 'add',
autorename: true,
mute: false
}));
xhr.send(file);
Then to download a file from dropbox do this.
var downloadFile = function(evt, file) {
evt.preventDefault();
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if (xhr.status === 200) {
var blob = new Blob([xhr.response], {type: ’application/octet-stream’});
FileSaver.saveAs(blob, file.name, true);
}
else {
var errorMessage = xhr.response || 'Unable to download file';
// Upload failed. Do something here with the error.
}
};
xhr.open('POST', 'https://content.dropboxapi.com/2/files/download');
xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
path: file.path_lower
}));
xhr.send();
}
FileSaver and Blob will not work on older browsers so you could add a workaround to them.
As other answers have noted, each session uploading or downloading the file will need to have access to a dropbox token. Sending someone else's token to a user is a security issue since having the token will give them complete control over the dropbox account. The only way to make this work is to have each person authenticate with Dropbox and get their own token.
At Form.io we've implemented both the authentication and the upload/download into our platform. This makes it really easy to build web apps with dropbox as a backend for files.
"I need the files to be uploaded to my account and the clients need not login to dropbox."
Then you'll really need to do the upload server-side. To do it client side would mean sending the access token to the browser, at which point any user of your app could use that access token to do whatever they wanted with your account. (E.g. delete all the other files, upload their private DVD collection, etc.)
For security reasons, I would strongly recommend doing the upload server-side where you can keep the access token a secret.
The answers given so far don't utilize the Dropbox javascript SDK which I think would prob be the best way to go about it. Check out this link here:
https://github.com/dropbox/dropbox-sdk-js/blob/master/examples/javascript/upload/index.html
which provides an example which is ofc dependent on having downloaded the SDK. (Edit: after playing with SDK I realize that it creates a POST request similar to the accepted answer in this thread. However something the popular answer omits is the presence of an OPTIONS preflight call that the sdk makes prior to the actual POST)
I might also add that something that is not shown in the dropbox sdk examples is that you can upload a blob object to dropbox; this is useful for instance if you want to dynamically extract images from a canvas and upload them and don't want to upload something that has been selected from the file system via the file uploaded input.
Here is a brief example of the scenario I'm describing:
//code below after having included dropbox-sdk-js in your project.
//Dropbox is in scope!
var dbx = new Dropbox.Dropbox({ accessToken: ACCESS_TOKEN });
//numerous stack overflow examples on creating a blob from data uri
var blob = dataURIToBlob(canvas.toDataUrl());
//the path here is the path of the file as it will exist on dropbox.
//should be unique or you will get a 4xx error
dbx.filesUpload({path: `unq_filename.png`, contents: blob})
Many thanks to #smarx with his pointers I was able to reach the final solution.
Also I have added a few extra features like listening to upload progress so that the users can be showed with the upload progress percentage.
HTML
<input type="file" name="file" id="file" onchange="doUpload(event)">
JavaScript
var doUpload = function(event){
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var arrayBuffer = reader.result;
var arrayBufferView = new Uint8Array( arrayBuffer );
var blob = new Blob( [ arrayBufferView ], { type: input.files[0].type } );
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL( blob );
$.ajax({
url: "https://api-content.dropbox.com/1/files_put/auto/YourDirectory/" + input.files[0].name,
headers: {
'Authorization':'Bearer ' +YourToken,
'Content-Length':input.files[0].size
},
crossDomain: true,
crossOrigin: true,
type: 'PUT',
contentType: input.files[0].type,
data: arrayBuffer,
dataType: 'json',
processData: false,
xhr: function()
{
var xhr = new window.XMLHttpRequest();
//Upload progress, litsens to the upload progress
//and get the upload status
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = parseInt( parseFloat(evt.loaded / evt.total) * 100);
//Do something with upload progress
$('#uploadProgress').html(percentComplete);
$('#uploadProgressBar').css('width',percentComplete+'%');
}
}, false);
},
beforeSend: function(){
// Things you do before sending the file
// like showing the loader GIF
},
success : function(result) {
// Display the results from dropbox after upload
// Other stuff on complete
},
});
}
reader.readAsArrayBuffer(input.files[0]);
}
U have used the PUT method as our only objective is to upload files,As per my studies on various resources ( StackOverflow and zacharyvoase ) A put method can stream large files, also its desigend to put files on a specified URI , if file exist the file must be replaced. A PUT method cannot be moved to a different URL other than the URL Specified.
The Risk
You are at risk by using access token at client side, there needs to be high security measures to mask the token. But modern Web dev tools like Browser consoles , Firebug etc can monitor your server requests and can see your access token.
upload.html
Upload
upload.js
$('#form_wizard_1 .button-submit').click(function () {
var ACCESS_TOKEN ="Your token get from dropbox";
var dbx = new Dropbox({ accessToken: ACCESS_TOKEN });
var fileInput = document.getElementById('files1');
var file = fileInput.files[0];
res=dbx.filesUpload({path: '/' + file.name, contents: file})
.then(function(response) {
var results = document.getElementById('results');
results.appendChild(document.createTextNode('File uploaded!'));
res=response;
console.log(response);
})
.catch(function(error) {
console.error(error);
});
}
I've some trouble into uploading a video to a form.
In my case, I need to upload some data with my video, so I left BackgroundUploader to use WinJS.xhr. But I can't figure it out how to convert my video file into something readable for my php.
My code:
var clickPicker = function () {
openPicker = Windows.Storage.Pickers.FileOpenPicker();
// We set the default location to the video library
openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.videosLibrary;
// Set de view to thumbnail
openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
// Extension allowed to be taken
openPicker.fileTypeFilter.replaceAll([".mp4", ".avi"]);
openPicker.pickSingleFileAsync().done(function (file) {
uploadInit(file);
}, function (err) {
// MISTAAAAAAAAAAAAAAAAKEEEEEEEEE
console.log(err.message);
});
};
var uploadInit = function (file) {
// Creating the blob
var objectURL = window.URL.createObjectURL(file);
var url = "http://localhost/vdm_bo/videos/uploader";
var d = new Date();
var data = new FormData();
data.append("data[Video][pseudo]", 'H4mm3R');
data.append('data[Video][postal_code]', '67340');
// Converting date to a datetile mysql
data.append('data[Video][date]', ISODateString(d));
data.append('data[Video][age]', '24');
data.append("data[Video][email]", 'bliblu#hotmail.fr');
data.append("data[Video][question_selected]", 'qA');
data.append("data[Video][video_file]", file, file.name);
WinJS.xhr({
type: "POST",
url: url,
data: data
}).done(function (res) {
console.log('succes');
}, function (err) {
console.log(err.message);
}, function (res) {
});
};
So, to debug this I serialize the answer, and here is what I get :
When uploading with the file (without blob) :
s:36:"[object Windows.Storage.StorageFile]";
When uploading with blob (window.URL.createObjectURL(file))
s:41:"blob:9A06AB11-8609-42DC-B0A9-7FB416E70A9D";
And when I'm uploading the video just with my html form
a:5:{s:4:"name";s:36:"9147cb17e216d5182908ad370ff16914.mp4";s:4:"type";s:9:"video/mp4";s:8:"tmp_name";s:23:"C:\wamp\tmp\php13C8.tmp";s:5:"error";i:0;s:4:"size";i:26454182;}
Does anyone have a clue how to make it work ? Or maybe I do it all wrong and it's not the way I'm suppose to convert my file (It's the way to do for images, maybe not for video)
Okay, I found a way to do that. First ou need to get the file with getFileAsync() and not the Picker. Then you can create a blob with the stream of your file and add this blob to your form.
Here my code
var videosLibrary = Windows.Storage.KnownFolders.videosLibrary;
videosLibrary.getFileAsync(file.name).then(
function completeFile(file) {
return file.openAsync(Windows.Storage.FileAccessMode.readWrite);
}).then(
function completeStream(stream) {
var d = new Date();
// Do processing.
var blob = MSApp.createBlobFromRandomAccessStream("video/mp4", stream);
var data = new FormData();
data.append("data[Video][pseudo]", 'H4mm3R');
data.append('data[Video][postal_code]', '67340');
// Converting date to a datetile mysql
data.append('data[Video][date]', ISODateString(d));
data.append('data[Video][age]', '24');
data.append("data[Video][email]", 'bliblu#hotmail.fr');
data.append("data[Video][question_selected]", 'qA');
data.append("data[Video][video_file]", blob, file.name);
return WinJS.xhr({ type: "POST", url: "http://localhost/vdm_bo/videos/uploader", data: data });
}).then(
function (request) {
console.log("uploaded file");
},
function (error) {
console.log("error uploading file");
});