【问题标题】:How to open a "Select folder" dialog from NodeJS (server-side, not browser)?如何从 NodeJS(服务器端,而不是浏览器)打开“选择文件夹”对话框?
【发布时间】:2019-01-10 08:10:20
【问题描述】:

为什么要在服务器端显示文件/文件夹对话框?

我正在构建一个打算在本地运行的项目(节点服务器端部分和浏览器中的客户端),我希望能够选择一个路径,将其添加到一些列表或 JSON 文件,然后在其中维护一些项目(webpack'ing、读取文件、通过 express 服务等)。

大多数情况下仅供个人使用,现在无论如何。

我要求通过 Node 而不是浏览器执行此操作的原因是,我可以以某种方式绕过现代浏览器中的安全隐患,即在选择文件夹时阻止在客户端显示完整的本地文件夹路径(来自<input> 标签)。

不仅如此,我也:

  • 不需要上传任何文件,或者
  • 不需要所选文件夹中包含的文件列表。

我只需要:

  • 一种以用户友好的方式选择文件夹的方法,并且...
  • 提交到服务器的路径
  • (或者让服务器提示它,并将其存储在某处)。

input标签为例:

<input id="open-project" type="file" />

这将产生这种类型的弹出窗口,非常适合挖掘文件夹、粘贴部分路径以快速导航到您需要的位置、转到您的快速访问/收藏夹等...

但它是用于选择文件,没有暴露路径,也没有任何有用的信息传递给服务器。

不过……

如果你切换到这个...

<input id="open-project" type="file" webkitdirectory directory />

您最终会看到这个可怕的对话框,它假定您要上传文件夹中包含的所有文件。


所以看起来<input> 并不是正确的选择。

也许有一个在服务器端执行此操作的现有模块?这样我就可以:

  • 从客户端“调用”它,例如通过 AJAX
  • 然后会在服务器上触发它
  • 然后显示文件夹选择提示

或者……

制作一个...浏览器中的树形视图...与节点端来回通信以挖掘本地文件系统...

有什么建议吗?

【问题讨论】:

  • 你终于解决了这个问题吗?....我也遇到了同样的情况....:)
  • @ÁngelBlanco 我最终使用 VueJS +“express”模块构建了一个基于浏览器的自定义文件浏览器。我定义了一个 POST 路由,它探索可用卷/驱动器的列表,还允许挖掘它们(一些系统目录除外)。一点点 HTML、CSS 和 JS 之后,很久以后......给我自己一个文件夹选择器!
  • @bigp - 你愿意分享那个基于浏览器的自定义文件浏览器吗?或者如果没有,你有什么灵感来创作它?这对我当前的项目有很大帮助。谢谢!

标签: javascript node.js windows path openfiledialog


【解决方案1】:

我通过生成一个子 powershell 进程并将该值传递回父进程来实现这一点。这只能在 Windows 服务器上工作,但这样的事情应该可以工作:

let psScript = `
Function Select-FolderDialog
{
    param([string]$Description="Select Folder",[string]$RootFolder="Desktop")

 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
     Out-Null     

   $objForm = New-Object System.Windows.Forms.FolderBrowserDialog
        $objForm.Rootfolder = $RootFolder
        $objForm.Description = $Description
        $Show = $objForm.ShowDialog()
        If ($Show -eq "OK")
        {
            Return $objForm.SelectedPath
        }
        Else
        {
            Write-Error "Operation cancelled by user."
        }
    }

$folder = Select-FolderDialog # the variable contains user folder selection
write-host $folder
`

这实际上是您需要提示文件夹位置的脚本,然后将其写入主机(类似于 console.log)

那么你需要执行这个脚本并处理输出:

var spawn = require("child_process").spawn,child;
child = spawn("powershell.exe",psScript);
child.stdout.on("data",function(data){
    console.log("Powershell Data: " + data);
});
child.stderr.on("data",function(data){
    //this script block will get the output of the PS script
    console.log("Powershell Errors: " + data);
});
child.on("exit",function(){
    console.log("Powershell Script finished");
});
child.stdin.end(); //end input

【讨论】:

  • 我在几个不同的小项目中使用的很好的答案。但是现在,由于我还无法确定的原因,它不再在前台弹出,而是在后台弹出......我尝试使用各种脚本让它没有运气就进入前台。有任何想法吗? (我试过foreach($p in (Get-Process powershell)){(New-Object -ComObject WScript.Shell).AppActivate(($p).MainWindowTitle)}之类的东西)
  • 你需要调用 spawn 像 spawn('powershell.exe', [psScript]);否则你的代码会出错。节点 12.18.3
  • 如果您想使用更好的文件夹浏览器对话框,我已经使用您的示例 here 解决了显示更用户友好、功能齐全的对话框的问题
猜你喜欢
  • 1970-01-01
  • 2021-11-02
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多