使用 JavaScript XHR 列出服务器目录
List server directory using JavaScript XHR
当我问到可以 javascript
列出服务器上的文件的问题时,每个人都回答“javascript
无法访问服务器文件系统,因为它是 client-side scripting language
”。但我认为这个答案只是部分正确,因为如果 dirlisting
启用,浏览器可以列出服务器目录的内容。因此,我决定尝试解析该输出 - 当您已经可以看到 xml
格式的所需数据时,无需使用 cgi
。所以这就是我所做的:
我正在使用 lighttpd
,lighttpd.conf
中的重要条目是:
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
用来测试 XHR
看起来像这样:
<?xml version="1.0"?>
<anchors>
<a>foo</a>
<a>bar</a>
</anchors>
目录列表页面,创建者 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
页面用于创建 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>
所有这些都工作正常(你在警告框中得到 'foo'),但是当我使用 request.open
目录而不是 xml
时,我什么也得不到,甚至在错误控制台中也没有.
您的代码有几个问题。对于初学者,在 JavaScript 中,您在 request.readyState
是 4
之前访问 request.responseXML
。此时,属性 应该不可用,因此您应该会收到一些错误。这可以很容易地解决。
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);
}
}
但是,您还有另一个问题。您正在尝试将输出解析为 XML,但它不是有效的 XML 文档,也不是有效的 HTML 文档。您需要用另一个元素包装输出才能使其成为有效的 XML 文档,因为只能有一个根节点。此外,XML 不支持
,因此也需要删除 or replaced。像下面这样的东西会起作用。
<?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>
您可能也有兴趣使用 responseType
属性 的 XMLHttpRequest
。如果将此 属性 设置为 'document'
,则可以解析 HTML 响应,而不是 XML 响应。
request.open('post', 'dir/', true);
request.responseType = 'document';
request.send();
当我问到可以 javascript
列出服务器上的文件的问题时,每个人都回答“javascript
无法访问服务器文件系统,因为它是 client-side scripting language
”。但我认为这个答案只是部分正确,因为如果 dirlisting
启用,浏览器可以列出服务器目录的内容。因此,我决定尝试解析该输出 - 当您已经可以看到 xml
格式的所需数据时,无需使用 cgi
。所以这就是我所做的:
我正在使用 lighttpd
,lighttpd.conf
中的重要条目是:
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
用来测试 XHR
看起来像这样:
<?xml version="1.0"?>
<anchors>
<a>foo</a>
<a>bar</a>
</anchors>
目录列表页面,创建者 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
页面用于创建 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>
所有这些都工作正常(你在警告框中得到 'foo'),但是当我使用 request.open
目录而不是 xml
时,我什么也得不到,甚至在错误控制台中也没有.
您的代码有几个问题。对于初学者,在 JavaScript 中,您在 request.readyState
是 4
之前访问 request.responseXML
。此时,属性 应该不可用,因此您应该会收到一些错误。这可以很容易地解决。
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);
}
}
但是,您还有另一个问题。您正在尝试将输出解析为 XML,但它不是有效的 XML 文档,也不是有效的 HTML 文档。您需要用另一个元素包装输出才能使其成为有效的 XML 文档,因为只能有一个根节点。此外,XML 不支持
,因此也需要删除 or replaced。像下面这样的东西会起作用。
<?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>
您可能也有兴趣使用 responseType
属性 的 XMLHttpRequest
。如果将此 属性 设置为 'document'
,则可以解析 HTML 响应,而不是 XML 响应。
request.open('post', 'dir/', true);
request.responseType = 'document';
request.send();