Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List Files on a server via front-end javascript

Tags:

javascript

A have a folder filled with files accessible to the end user, and am working on a javascript file to parse through them and deliver them as needed. However, rather than manually updating the list, I'd like the javascript to scan the folder and then list iterate through an array of the files in that folder. Is there a decent way in front-end JS to do this? All solutions I've looked into have turned out to be purely for Node.

For example, say I have a folder structure like so...

/ (Web Root)
|__ /Build_a_card
|__ /Cool pictures
  |__ /Summer Pictures
       summer_dog.gif
       smiling_sun.svg
  |__ /Winter Pictures
       snowman.png
  cat.jpg

And then in the javascript I'd run something like

var image_list = get_list("/Cool Pictures");
build_select_list(image_list);

function get_list(folder_to_look_in){
   var the_list = ???
   return the_list;
}
...

And then, for example, the JS is run, and after some parsing, the user would see...

<select>
  <option value="summer_pictures/summer_dog.gif">summer_dog.gif</option>
  <option value="summer_pictures/smiling_sun.svg">smiling_sun.svg</option>
  <option value="winter_pictures/snowman.png">snowman.png</option>
  <option value="cat.jpg">cat.jpg</option>
</select>

In an ridiculous world, since the individual files in the folder are accessible to javascript, hypothetically I could brute-force every single possible file name in the folder and return success on each one:

function get_list(folder){
  var list_of_files = {};
  var starting_character = 0;
     list_of_files = every_single_option({starting_character}, 0, 40, folder)
  }
}
function every_single_option(existing_characters, current_depth, max_depth, folder){
  this_string = String.fromCharCode(existing_characters);
  if (request_url(this_string, folder)){
     there_array[this_string] = this_string;
  }
  var there_array = {}
  var i;
  if (current_depth < max_depth){
    while (i < 127){
        let temp_array = there_array;
        temp_array[i] = i;
        mix_source(there_array, every_single_option(existing_characters, current_depth + 1, max_depth, folder))
    }
}
return there_array;
}
function request_url(url, folder){
  var oReq = new XMLHttpRequest();
  oReq.addEventListener("load", reqListener);
  oReq.open("GET", "/" + folder + "/" + url);
  oReq.send();
}
function mix(source, target) {
   for(var key in source) {
     if (source.hasOwnProperty(key)) {
        target[key] = source[key];
     }
   }
}

but as mentioned, doing it that way would be ridiculous (both unusably slow and very bad code design, resorting to brute-forcing your own website is just dumb.)

but it does hypothetically prove that there's no reason javascript shouldn't be able to just get a directory listing assuming public permissions. Alternatively, I could make some API with the backend that allows fetching a JSON that lists it, but that's requiring backend code for something that's a frontend process. I'm trying to pull this off with something sane and simple, but the question is... how?

(If you insist on posting a jquery way to do this, please also post a non-jquery way as well as there is no jquery available in my environment.)

like image 277
lilHar Avatar asked Dec 22 '25 09:12

lilHar


1 Answers

So, refusing to admit it's impossible, I engineered a solution that works, and requires no API. That said, the server has to not be actively blocking the javascript from viewing the directory. In other words, the server hasn't turned indexing off, and the directory doesn't have an index.html or equivalent to rewrite any attempt to index, and the server isn't doing some url-rewriting. In other words, this should work in any server environment that doesn't rewrite or block indexes.

Here's a rough draft (still buggy, needs finished):

var request = new XMLHttpRequest();
request.open('GET', '/my/directory/', true);

request.onload = function() {
  if (request.status >= 200 && request.status < 400) {
    // Success!
    var resp = request.responseText;
  }
};

request.send();
var directory_listing = resp;
var regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i;
var match, files = [];

while ((match = regexp.exec(resp)) != null) {
  files.push(match.index);
}

console.log(files);
like image 165
lilHar Avatar answered Dec 23 '25 22:12

lilHar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!