由于我必须使用的架构可能会破坏很多非常好的软件设计规则,我需要将一条消息从在 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/