【问题标题】:List server directory using JavaScript XHR使用 JavaScript XHR 列出服务器目录
【发布时间】:2025-12-27 07:45:12
【问题描述】:

当我问到可以javascript列出服务器上的文件时,每个人都回答“javascript无法访问服务器文件系统,因为它是client-side scripting language”。但我认为这个答案只是部分正确,因为如果启用了dirlisting,浏览器可以列出服务器目录的内容。因此,我决定尝试解析该输出 - 当您已经可以看到 xml 格式的数据时,无需使用 cgi。所以这就是我所做的:

我正在使用lighttpdlighttpd.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

用于测试XHRtest.xml看起来像这样:

<?xml version="1.0"?>
<anchors>
 <a>foo</a>
 <a>bar</a>
</anchors>

目录列表页面,由lighttpdmod_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">&nbsp;</td><td class="s">- &nbsp;</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 html xml xmlhttprequest lighttpd


    【解决方案1】:

    您的代码存在一些问题。对于初学者,在您的 JavaScript 中,您在 request.readyState4 之前访问 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 不支持&amp;nbsp;,因此也需要删除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>
    

    您可能还对使用XMLHttpRequestresponseType 属性感兴趣。如果将此属性设置为'document',则可以解析 HTML 响应,而不是 XML 响应。

    request.open('post', 'dir/', true);
    request.responseType = 'document';
    request.send();
    

    【讨论】:

    • request.readyState 为简化示例代码而被省略,xml 文件已由mod_dirlisting.so 服务器模块生成,因此我无法在其中操作其半不正确的输出(&amp;nbsp 等)无论如何,但我可以选择通过使用request.responseType = 'document' 解析输出来绕过它,这实际上是我问题的直接答案。谢谢。