When I asked the question can javascript
list files on the server, everyone answered with "javascript
cannot access server filesystem because it is a client-side scripting language
". But I thought that answer is only partially true, because browser can list the contents of the server directory if dirlisting
is enabled. So, I decided to try to parse that output - no need to use cgi
when you can already see the data you need in xml
format. So here is what I did:
I am using lighttpd
, and important entries in lighttpd.conf
are:
dir-listing.activate = "enable" #enables directory listing
dir-listing.auto-layout = "disable" #simplifies the list style
mimetype.assign = ( ".xml" => "text/xml" ) #deals with xmls
test.xml
used to test XHR
looks like this:
<?xml version="1.0"?>
<anchors>
<a>foo</a>
<a>bar</a>
</anchors>
Directory listing page, created by lighttpd
mod_dirlisting.so
:
<?xml version="1.0" encoding="iso-8859-1"?>
<h2>Index of /directory/</h2>
<div class="list">
<table summary="Directory Listing" cellpadding="0" cellspacing="0">
<thead><tr><th class="n">Name</th><th class="m">Last Modified</th><th class="s">Size</th><th class="t">Type</th></tr></thead>
<tbody>
<tr><td class="n"><a href="../">Parent Directory</a>/</td><td class="m"> </td><td class="s">- </td><td class="t">Directory</td></tr>
<tr><td class="n"><a href="foo">foo</a></td><td class="m">2015-Jan-03 13:24:12</td><td class="s">39.4K</td><td class="t">application/octet-stream</td></tr>
</tbody>
</table>
</div>
test.html
page used to create XHR
:
<html><head></head><body><script>
if (window.XMLHttpRequest) var request = new XMLHttpRequest();
else var request = new ActiveXObject('Microsoft.XMLHTTP');
request.open('post', 'test.xml', true);
request.send();
if (request) request.onreadystatechange = function() alert(request.responseXML.getElementsByTagName('a')[1].childNodes[0].nodeValue);
</script></body></html>
All of which work fine (you get 'foo' in an alert box), but when I request.open
directory instead of xml
, I get nothing, not even in error console.
You have a couple of issues with your code. For starters, in your JavaScript you are accessing request.responseXML
before request.readyState
is 4
. At this point, that property should not be available, so you should be getting some errors on that. This can be fixed fairly easily.
if (window.XMLHttpRequest) var request = new XMLHttpRequest();
else var request = new ActiveXObject('Microsoft.XMLHTTP');
request.open('post', 'dir/', true);
request.send();
request.onreadystatechange = function() {
if (request.readyState === 4) {
alert(request.responseXML.getElementsByTagName('a')[1].childNodes[0].nodeValue);
}
}
However, you have another issue. You are trying to parse your output as XML, but it is not a valid XML document, or a valid HTML document for that matter. You would need to have another element wrapping the output for it to be a valid XML document, as there can only be one root node. Additionally,
is not supported in XML, so that would also need to be removed or replaced. Something like the following would work.
<?xml version="1.0" encoding="iso-8859-1"?>
<xml>
<h2>Index of /directory/</h2>
<div class="list">
<table summary="Directory Listing" cellpadding="0" cellspacing="0">
<thead><tr><th class="n">Name</th><th class="m">Last Modified</th><th class="s">Size</th><th class="t">Type</th></tr></thead>
<tbody>
<tr><td class="n"><a href="../">Parent Directory</a>/</td><td class="m"></td><td class="s">- </td><td class="t">Directory</td></tr>
<tr><td class="n"><a href="foo">foo</a></td><td class="m">2015-Jan-03 13:24:12</td><td class="s">39.4K</td><td class="t">application/octet-stream</td></tr>
</tbody>
</table>
</div>
</xml>
You might also be interested in using the responseType
property of the XMLHttpRequest
. If you set this property to 'document'
, you can parse HTML response, rather than XML response.
request.open('post', 'dir/', true);
request.responseType = 'document';
request.send();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With