so.. i have a XMLHttpRequest image uploader and i don't know how to limit the image uploader to only upload images nothing else and i have put a limit on the file size so its 3mb so its not too big
question how do you limit the image uploader to only upload images nothing else
image uploader code
// following line is not necessary: prevents running on SitePoint servers
if (location.host.indexOf("sitepointstatic") >= 0) return
var xhr = new XMLHttpRequest();
if (xhr.upload && file.type == ("image/jpg"||"image/png") && file.size <= $id("MAX_FILE_SIZE").value) {
// create progress bar
var o = $id("progress");
var progress = o.appendChild(document.createElement("p"));
progress.appendChild(document.createTextNode("upload " + file.name));
// progress bar
xhr.upload.addEventListener("progress", function(e) {
var pc = parseInt(100 - (e.loaded / e.total * 100));
progress.style.backgroundPosition = pc + "% 0";
}, false);
// file received/failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
progress.className = (xhr.status == 200 ? "success" : "failure");
}
};
// start upload
xhr.open("POST", "upload.php", true);
xhr.setRequestHeader("X_FILENAME", file.name);
xhr.send(file);
}
else
{
alert("file in unsported at this time " + file.type);
}
I just want to check their file extension just to be clear.
Thanks for your help
Don't rely on javascript to filter uploaded files. I would suggest only checking the file extension - it will work for honest users 99.9% of the time, and malicious users will find a way around any javascript.
The security comes from server-side verification. On the server, you can check by using a function or library to parse the file as an image. For example, you can run a function to check the image's dimensions, which will throw an error if the file is not an image.
Related
I have some javascript that sends a XMLHttpRequest to a PHP file. This PHP file sends a response, and javascript is supposed to create a URL and redirect to it, using the response text as a parameter. In all other browsers it works fine, but Firefox won't include the response text in the URL.
This is the javascript example:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'filename.php', true);
xhr.onreadystatechange = function(e){
var id = e.currentTarget.responseText;
var urlWithId = "restofurl?id=" + id;
window.location.href = urlWithId;
}
xhr.send(fd);
and filename.php is just a number at the moment:
<?php
echo "3";
?>
I have tried putting other parts of the url (up to the whole url) in the php part, and firefox always cuts out exactly that part. I have also tried copying the response several times to different variable, copying it character by character, putting it in a function that just returns the input again,...
This is only going to be on my own computer, so I don't need to worry about any security issues, so I'm mostly looking for an easy way to cheat around this rather than the way it would be done professionally. Does anyone have any idea?
This is a basic example, you actually have to test readyState status. If i remember well, it is also safer to set the event function before sending the request (not really sure of that).
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
//do something with this.responseText
}
};
xhr.open("POST", url, true);
xhr.send();
EDIT:
This is one of the reasons why i use frameworks, for the old browser support, but this is not an answer. To be more precise, in the past (present?), browsers used to implement exotic functions. It's been a long time i didnt bother to use XHR objects directly, last time it was for file uploads with loading bar (canvas). It shows you the basic way to handle some stuff. This is longer and a bit old fashioned, but well, it works.
function customXHR(){
if(window.XMLHttpRequest){
return new window.XMLHttpRequest;
}else{
try{ //the weird ones
return new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
catch(ex){
return null;
}
}
}
var xhr = customXHR(), pleaseStop = false, startDraw = false;
if(xhr){
xhr.addEventListener('load', function(e){
var jsonRep;
if(!pleaseStop){
//did use a JSON response
jsonRep = $.parseJSON(e.target.responseText);
//do the rest, we finished
}
}, false);
xhr.addEventListener('error', function(e){
//error
pleaseStop = true;
}, false);
xhr.upload.addEventListener('progress', function(e){
//why not let this as an example!
//file_size must be retreive separately, i fear
if(e.lengthComputable && file_size > 0 && !pleaseStop && startDraw){ draw_progress(e.loaded / file_size); }
}, false);
xhr.addEventListener('loadstart', function(e){
//can be used too
}, false);
xhr.addEventListener('readystatechange', function(e){
if(e.target.status == 404 && !pleaseStop){
//error not found
pleaseStop = true;
}
if(e.target.readyState == 2 && e.target.status == 200){
startDraw = true;
}
/*if(e.target.readyState == 4){
//not used here, actually not exactly the same as 'load'
}*/
}, false);
xhr.open("POST", url, true);
xhr.send();
} //else no XHR support
I´m starting to customize/improve an old audio editor project. I can import audio tracks to my canvas VIA drag&drop from my computer. The thing is that I also would like to use audio tracks already stored in the server just clicking over a list of available tracks... instead of use the <input type="file"> tags. How can I read the server side files with a FileReader?Ajax perhaps? Thanks in advance.
This is the code for the file reader:
Player.prototype.loadFile = function(file, el) {
//console.log(file);
var reader = new FileReader,
fileTypes = ['audio/mpeg', 'audio/mp3', 'audio/wave', 'audio/wav'],
that = this;
if (fileTypes.indexOf(file.type) < 0) {
throw('Unsupported file format!');
}
reader.onloadend = function(e) {
if (e.target.readyState == FileReader.DONE) { // DONE == 2
$('.progress').children().width('100%');
var onsuccess = function(audioBuffer) {
$(el).trigger('Audiee:fileLoaded', [audioBuffer, file]);
},
onerror = function() {
// on error - show alert modal
var tpl = (_.template(AlertT))({
message: 'Error while loading the file ' + file.name + '.'
}),
$tpl = $(tpl);
$tpl.on('hide', function() { $tpl.remove() })
.modal(); // show the modal window
// hide the new track modal
$('#newTrackModal').modal('hide');
};
that.context.decodeAudioData(e.target.result, onsuccess, onerror);
}
};
// NOTE: Maybe move to different module...
reader.onprogress = function(e) {
if (e.lengthComputable) {
$progress = $('.progress', '#newTrackModal');
if ($progress.hasClass('hide'))
$progress.fadeIn('fast');
// show loading progress
var loaded = Math.floor(e.loaded / e.total * 100);
$progress.children().width(loaded + '%');
}
};
reader.readAsArrayBuffer(file);
};
return Player;
Thanks for the suggestion micronn, I managed to make a bypass without touch the original code. The code as follows is the following:
jQuery('.file_in_server').click(function()
{
var url=jQuery(this).attr('src');//Get the server path with the mp3/wav file
var filename = url.replace(/^.*[\\\/]/, '');
var path="http://localhost/test/audio/tracks/"+filename;
var file = new File([""], filename); //I need this hack because the original function recives a buffer as well as the file sent from the web form, so I need it to send at least the filename
var get_track = new XMLHttpRequest();
get_track.open('GET',path,true);
get_track.responseType="arraybuffer";
get_track.onload = function(e)
{
if (this.status == 200) //When OK
{
Audiee.Player.context.decodeAudioData(this.response,function(buffer){ //Process the audio toward a buffer
jQuery('#menu-view ul.nav').trigger('Audiee:fileLoaded', [buffer, file]); //Send the buffer & file hack to the loading function
},function(){
alert("Error opening file");
jQuery('#newTrackModal').modal('hide');
});
}
};
get_track.send();
});
After this, in the fileLoaded function, the track is added to the editor.
var name = 'Pista ' + Audiee.Collections.Tracks.getIndexCount();
track = new TrackM({buffer: audioBuffer, file: file, name: name}); //being audioBuffer my buffer, file the fake file and name the fake file name
Audiee.Collections.Tracks.add(track);
And... thats it!
I am having a problem with this code. i wanna process the cordova android image url ( ie. stored in localStorage ) to upload in my web server.
function processImages(list, i){
var images = list[i].images;
images && images.forEach(function(image, j){
window.resolveLocalFileSystemURI(image, function(entry) {
var reader = new FileReader();
reader.onloadend = function(evt) {
list[i].images[j] = evt.target.result;
}
reader.onerror = function(evt) {
alert("error");
}
entry.file(function(f) {
//alert("Image is added");
reader.readAsDataURL(f);
}, function(e) {
alert('Image process error : '+e);
});
});
});
}
This code runs good if i am enabling #alert("Image is added"); this alert.
without this alert the app is shutting down by giving error unfortunately appname has stopped.
Its also not working for n number of images of size more than 2mb.
Note : consider async call and image size is more than 2mb each minimum 10 image per record.
Please help me !!!
Thanks
Is it possible with javascript to convert text from text-input and upload it as a file to server? I need to add to page something like text editor to open text file, then change it and upload to server as file but not as value of parameter in post request.
So is it possible to do?
Thanks.
If the browser supports XMLHttpRequest 2 (see http://caniuse.com/xhr2), you have an option.
The Uploading a file or blob: xhr.send(Blob) section of the HTML5 Rocks Tutorial (New Tricks in XMLHttpRequest2) has some sample code to get you started:
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.onload = function(e) { ... };
// Listen to the upload progress.
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
}
};
xhr.send(blobOrFile);
}
upload(new Blob(['hello world'], {type: 'text/plain'}));
Hi all I have this code:
function test()
{
req = new XMLHttpRequest();
req.upload.addEventListener("progress", updateProgress, false);
req.addEventListener("readystatechange", updateProgress, false);
req.addEventListener("error", uploadFailed, false);
req.addEventListener("abort", uploadCanceled, false);
var data = generateRandomData(currentPayloadId);
totalSize = data.length;
req.open("POST", "www.mydomain.com/upload.aspx");
start = (new Date()).getTime();
req.send(data);
}
function updateProgress(evt)
{
if (evt.lengthComputable) {
total = totalSize = evt.total;
loaded = evt.loaded;
}
else {
total = loaded = totalSize;
}
}
Also, my server responds to the initial OPTIONS request for upload.aspx with 200 and the Access-Control-Allow-Origin: *
and then the second request POST happens
Everything seems in place and it's working great on FireFox but on G Chrome the updateProgress handler is not getting called but only once and then the lengthComputable is false.
I needed the Access-Control-Allow-Origin: * because this is a cross-domain call, the script parent is a resource on a different server then the upload.aspx domain
Anyone can give me some clues, hints, help please? is this a known issue with G Chrome?
Thank you!
Ova
I think I have a solution for your problem
I don't know what is behind this function "generateRandomData()"
var data = generateRandomData(currentPayloadId)
It is working when I change into this:
var data = new FormData();
data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
Small explanation: You need manually to append to form data an file input form, where fileToUpload is <input type="file" name="fileToUpload" id="fileToUpload" />
And in your updateProgress function in IF part you can add something like this to track progress console.log(evt.total +" - "+ evt.loaded)
This is working in Google Chrome browser. I have tested in new browser version 57
I made for myself an upload progress form 4 years ago, which means that this code is working in old browser version too.
A whole code snippet will be looking like this
function test()
{
req = new XMLHttpRequest();
req.upload.addEventListener("progress", updateProgress, false);
req.addEventListener("readystatechange", updateProgress, false);
req.addEventListener("error", uploadFailed, false);
req.addEventListener("abort", uploadCanceled, false);
//var data = generateRandomData(currentPayloadId);
var data = new FormData();
data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
totalSize = data.length;
req.open("POST", "www.mydomain.com/upload.aspx");
start = (new Date()).getTime();
req.send(data);
}
function updateProgress(evt)
{
if (evt.lengthComputable) {
total = totalSize = evt.total;
loaded = evt.loaded;
console.log(evt.total +" - "+ evt.loaded)
}
else {
total = loaded = totalSize;
}
}
I had this problem when the page your are loading doesn't contain a
Content-Length: 12345
in the header, where 12345 is the length of the response in bytes. Without a length parameter, the progress function has nothing to work on.
First, make sure that "www.example.com" is added to the manifest.json, like so:
manifest.json
{
..
"permissions": [
"http://www.example.com/",
"https://www.example.com/",
],
..
}
Then I think your example should work.
For more information about using xhr in google chrome extensions the docs are here.
Also the CSP docs are worth taking a look at if what I provided above does not.
This could simply be a compatibility issue with the XMLHttpRequest.upload property. It returns an XMLHttpRequestUpload object, but if you try find that object spec in MDN it doesn't exist so how do we know which browsers fully support it.
XMLHttpRequest.upload Compatability
Have you tried listening for progress directly on the xhr:
req.addEventListener("progress", updateProgress, false);
I use jQuery for progress like that:
$.ajax({
url : furl,
type : method,
data : data,
//...
},
xhr : function () {
//upload Progress
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//update progressbar
$(".progress-bar").css("width", + percent + "%");
$(" .status").text(position + " / " + total + " (" + percent + "%)");
}, true);
}
return xhr;
},