javascript - 将消息从浏览器中运行的 Javascript 发送到 Windows 批处理文件

标签 javascript windows batch-file

由于我必须使用的架构可能会破坏很多非常好的软件设计规则,我需要将一条消息从在 ​​Web 浏览器中运行的一些 javascript 代码发送到同一台机器上的 Windows 批处理文件。操作系统为 Windows Vista 或更高版本。使用的浏览器主要是 Chrome 和 Firefox。 jQuery 也与 javascript 一起使用。

浏览器已连接到互联网,并且涉及到服务器,因此我可以将消息中继到服务器,然后再到批处理文件。现在我有一个每分钟左右运行一次的批处理文件,理论上可以向服务器查询任何消息。除此之外,我没有什么好主意。

此外,这是一个“封闭”系统。客户端浏览器、客户端系统和服务器都在我的完全控制之下。这不是一般公众在浏览器中运行 Javascript 的情况。可以操纵客户端计算机以接收消息。

发送此消息的好方法是什么?

最佳答案

1。本地 HTTP 服务器

从 JavaScript 向本地 HTTP 服务器发送包含您的命令的 AJAX 请求。所有现代浏览器都支持跨域 AJAX。服务器可以将命令作为参数传递给批处理文件。 确保无法从网络访问服务器

这种方法的优点是您可以将命令的响应发送回 JavaScript。

  • JavaScript:

    $.post('http://localhost:8080', {command: '...'});
    
  • Bottle.py 服务器:

    #!/usr/bin/python
    from bottle import run, route, request, response
    import subprocess
    
    @route('/', method='POST')
    def index():
        command = request.POST['command']
        result = subprocess.check_output(['batchfile.bat', command], shell=True)
    
        response.set_header('Access-Control-Allow-Origin', '*')
        return result
    
    run(host='localhost', port=8080, reloader=True)
    
  • 或者Apache/nginx下的PHP:

    $result = shell_exec("batchfile.bat " . escapeshellarg($_POST['command']));
    
  • 或者 PHP 中的守护进程:

    为了额外的乐趣,它具有完整的 shell 访问权限并且可以异步运行命令,这允许在不阻塞的情况下启动桌面应用程序。它不需要 Apache。

    开始:php.exe -f batrunner_daemon.php

    使用:$.get('http://localhost:33333/ping -h', function(response) { console.log(response) });

    $host = '127.0.0.1';
    $port = 33333;
    $async = false; // enable to run commands without blocking the server (useful for GUI applications)
    
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    $open = @socket_bind($socket, $host, $port);
    if ($open) {
        echo "\nListening on http://{$host}:{$port}";
    } else {
        echo "\nError. Port {$port} in use";
        exit;
    }
    socket_listen($socket, 1);
    
    while(1) {
        $connection = socket_accept($socket);
        $http_request = socket_read($connection, 32768);
        $command = rawurldecode(substr(strstr($http_request, "\r\n", true), 5, -9));
    
        echo "\nRunning: {$command}...";
    
        if ($async) {
            $response = pclose(popen('start "" /B ' . $command, 'r')) ? 'error' : 'success';
        } else {
            $response = shell_exec($command);
        }
    
        echo " Done.";
    
        socket_write($connection, implode("\r\n", array(
            'HTTP/1.1 200 OK',
            'Content-Type: text/plain; charset=UTF-8',
            'Connection: close',
            'Content-Length: ' . strlen($response),
            'Access-Control-Allow-Origin: *',
            "\r\n" . $response
        )));
        socket_close($connection);
    }
    

    为简单起见,它没有正确的错误处理并允许任何站点在您的计算机上执行任何操作,使用风险自负。

    Access-Control-Allow-Origin: * 表示任何站点都可以接收来自 shell 的响应。没有这个 header ,他们显然仍然可以运行命令,但无法接收响应。


2。 URI 方案

我试验了@mamdrood 的想法,结果证明它非常简单,比 HTTP 服务器简单多了。

  • 在 HTML 中,您可以像这样调用批处理文件:

    <a href="batrunner://somecommand">Wipe all files</a>
    
  • 下面是 C:\mybatfile.bat 中的批处理文件如何解析命令:

    @echo off
    SET command=%1
    SET command=%command:batrunner://=%
    echo %command%
    

    我对批处理文件不是很熟悉,我的命令名称解析代码可能存在漏洞。如果您知道得更多,请更新此答案。

  • 要将您的批处理文件与 batrunner:// 协议(protocol)相关联,请创建 batrunner.reg 并运行一次。用 C:\\mybatfile.bat 代替你的脚本,路径应该被转义。

    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOT\batrunner]
    "URL Protocol"=""
    
    [HKEY_CLASSES_ROOT\batrunner\shell]
    
    [HKEY_CLASSES_ROOT\batrunner\shell\open]
    
    [HKEY_CLASSES_ROOT\batrunner\shell\open\command]
    @="C:\\mybatfile.bat %1"
    

关于javascript - 将消息从浏览器中运行的 Javascript 发送到 Windows 批处理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10125881/

相关文章:

windows *.bat 文件用户输入和验证

batch-file - 为什么这个 .bat cmd 总是命中一个我不打算让它命中的子例程?

javascript - 调试 Bootstrap 3 模板

javascript - 在 polymer 中使用 core-ajax 和 xml 构建新元素

javascript - 如何将表单输入的值获取到变量中

.net - 如何在 Windows 上查询打印队列

Windows 应用程序数据目录

windows - 将每个文件复制到每个文件夹

batch-file - set/p 没有像宣传的那样工作

javascript - 谷歌 javascript map getCurrentPosition