如何使HTML链接打开文件夹

126

我需要让应用程序的用户通过在网页内点击链接来打开文件夹。文件夹的路径位于网络上,可以从任何地方访问。我很确定这没有简单的方法,但也许我错了?


4
我已经回答了下面的问题;这是企业Web应用程序的常见要求,但由于错误的安全措施几乎不可能实现(在可信任的HTTP页面中启用文件链接应该是可能的)。我只在Windows上进行了广泛测试。 - Andrew Duffy
10个回答

120

你想在Windows Explorer中打开共享文件夹吗?你需要使用一个file:链接,但有一些注意事项:

  • 如果链接是转换过的UNC路径(file://server/share/folder/),则Internet Explorer可以工作。
  • 如果链接以五个斜杠的形式呈现(file://///server/share/folder),并且用户已经禁用了通过HTTP服务的页面上的file:链接的安全限制,那么Firefox就可以工作。值得庆幸的是IE也接受这种格式的链接。
  • Opera、Safari和Chrome无法在通过HTTP服务的页面中打开file:链接。

5
仅在IE浏览器中,当UNC路径和包含链接的网站位于同一域中时,才能访问,也就是说仅限于局域网内。 - Stefan Steiger
7
我认为这不再正确——更新的IE版本似乎也会像Chrome/Safari等浏览器一样阻止这种行为。 - ZeekLTK
1
我刚在IE 11中尝试了一下,实际上你可以打开一个本地文件而不需要下载它(就像打开一个已经存在的文件路径)。但在Chrome中仍然无法做到这点。 - Hohohodown
5
你可以通过 LocalLinks Chrome扩展程序 让它在Chrome中运行。感谢这个StackOverflow回答 - Zach Johnson
1
@Andrew Duffy,有没有任何文档说明Google Chrome正在阻止这种行为?我想更多地了解这个问题。 - clhy
显示剩余2条评论

9

在网络上,URL file://[servername]/[sharename] 应该打开共享文件夹的资源管理器窗口。


能否使用相对路径打开本地机器上的文件? - Protagonist

7
有点晚了,但最近我也必须为自己解决这个问题,尽管情况略有不同,但仍然可以帮助到其他处于类似情况的人。我在笔记本电脑上使用xampp,在Windows上运行纯本地网站应用程序。(我知道这是非常特定的环境)。在这种情况下,我使用HTML链接到一个PHP文件并运行:
shell_exec('cd C:\path\to\file');
shell_exec('start .');

这将打开一个本地的Windows资源管理器窗口。

1
有潜力,但在 Firefox 中运行时标签页会挂起。(似乎是正在处理会话或其他内容,因为我可以访问其他网站,但是该网站似乎已经挂起,即使在其他标签页中也是如此!) - Stephen R
我刚在Firefox中测试了它,对我来说可以工作,但我无法指定要打开的文件夹,它只会在php文件的根目录中打开。 - Lucas Taulealea
1
@LucasTaulealea 我不知道为什么这个答案没有得到更多的赞。我只想添加一个小修正:在我的情况下,使用shell_exec('start C:\path\to\file');就足够了,似乎cd部分是不必要的,并且支持文件夹和文件。 - Kaddath
@Kaddah 可能之所以没有得到更多的赞是因为这个解决方案只在 Web 服务器运行在与您的 Web 浏览器相同的计算机上时才有效。大多数人可能正在寻找从企业网络网站提供 Windows 共享文件的方法。 - JamesHoux

6

如果安全设置达到了中等水平,使用 file:///// 就无法正常工作。

如果你只想让用户能够下载/查看位于网络或共享上的文件*,你可以在 IIS 中设置虚拟目录。在属性选项卡中,确保选择了“位于另一台计算机上的共享”并且“连接为...”是一个可以访问网络位置的帐户。

从网页链接到虚拟目录(例如:http://yoursite/yourvirtualdir/),这将在 Web 浏览器中打开目录视图。

*您可以允许虚拟目录具有写权限,以允许用户添加文件,但我没有尝试过,并且假设网络权限会覆盖此设置。


这在今天非常相关,因为Chrome和较新版本的IE将阻止非文件网页访问本地file://资源。此外,可以设置在IIS Express中运行,但必须手动添加和运行。 - Schmuli

5
我解决的方法是在每个人的计算机上安装本地 Web 服务,监听例如端口 9999 并在接收到指令时本地打开一个目录。这里是我的示例 Node.js Express 应用程序:
import { createServer, Server } from "http";

// server
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";

// other
import util from 'util';
const exec = util.promisify(require('child_process').exec);

export class EdsHelper {
    debug: boolean = true;
    port: number = 9999
    app: express.Application;
    server: Server;

    constructor() {
        // create app
        this.app = express();
        this.app.use(cors());
        this.app.use(bodyParser.json());
        this.app.use(bodyParser.urlencoded({
            extended: true
        }));

        // create server
        this.server = createServer(this.app);

        // setup server
        this.setup_routes();
        this.listen();
        console.info("server initialized");
    }

    private setup_routes(): void {
        this.app.post("/open_dir", async (req: any, res: any) => {
            try {
                if (this.debug) {
                    console.debug("open_dir");
                }

                // get path
                // C:\Users\ADunsmoor\Documents
                const path: string = req.body.path;

                // execute command
                const { stdout, stderr } = await exec(`start "" "${path}"`, {
                    // detached: true,
                    // stdio: "ignore",
                    //windowsHide: true,    // causes directory not to open sometimes?
                });

                if (stderr) {
                    throw stderr;
                } else {
                    // return OK
                    res.status(200).send({});
                }
            } catch (error) {
                console.error("open_dir >> error = " + error);
                res.status(500).send(error);
            }
        });
    }

    private listen(): void {
        this.server.listen(this.port, () => {
            console.info("Running server on port " + this.port.toString());
        });
    }

    public getApp(): express.Application {
        return this.app;
    }

}

以本地用户身份而非管理员身份运行此服务很重要,否则该目录可能永远无法打开。
从您的Web应用程序向localhost发出POST请求:http://localhost:9999/open_dir,数据:{ "path": "C:\Users\ADunsmoor\Documents" }


5

请确保您的文件夹权限设置允许目录列表,然后只需使用chmod 701将锚点指向该文件夹(尽管这可能存在风险)。

例如:

<a href="./downloads/folder_i_want_to_display/" >Go to downloads page</a>

请确保该目录中没有任何index.html或其他索引文件。

这个答案是有效的。 "允许目录列表" 部分非常重要。如果不允许,您可以启用它,但对于每个服务器应用程序来说都是不同的。 - Travis
使用锚点标签是否可以使用相对路径打开本地机器上的文件? - Protagonist

3

您还可以复制链接地址并将其粘贴到新窗口中,以绕过安全性。这在chrome和firefox中都有效,但您可能需要在firefox中添加斜杠。


3

我正在寻找文件系统访问API,最终进入了这个问题。

我知道该API不允许打开指向文件夹的HTML链接,但它确实允许打开本地文件夹和文件。更多信息请参见这里:

https://web.dev/file-system-access/


2

希望这能在某一天对某个人有所帮助。我正在制作一个小的概念验证,并遇到了这个问题。一个按钮,onClick会显示文件夹的内容。下面是HTML代码:

<input type=button onClick="parent.location='file:///C:/Users/' " value='Users'>

3
Chrome 给我一个错误提示:不允许加载本地资源:<URL>。 - Dave Sottimano
1
@Dave Sottimano,我刚刚测试了一下。在我的Google Chrome浏览器中,版本号为84.0.4147.135(官方版本)(64位),可以正常工作。 - Nagaraja JB
这只是为我下载文件,而不是在其原生应用程序中运行它。 - Shawn

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接