我有一个自定义的URL协议处理程序cgit:[...]
它启动一个后台进程,在本地机器上配置一些东西。该协议运行良好,我正在从JavaScript (目前正在使用document.location = 'cgit:[...]'
)启动它,但实际上我希望JavaScript等待相关程序退出。
因此,基本上,我希望JavaScript执行的步骤:
cgit:[...]
cgit:[...]
退出代码:
function launchCgit(params)
{
showProgressBar();
document.location="cgit:"+params;
document.addEventListener( /* CGit-Program exited event */, hideProgressBar );
}
或者:
function launchCgit(params)
{
showProgressBar();
// setLocationAndWait("cgit:"+params);
hideProgressBar();
}
如果可能的话有什么想法吗?
发布于 2016-08-12 09:58:55
由于我没有找到合适的方法来使用ajax请求或任何类似的方法来解决我的问题,所以我最终使用了包括XmlHttpRequest
在内的一种丑陋的工作环境来解决我的问题。
对于启动协议,我仍在使用document.location=cgit:[...]
我正在使用一个服务器端系统,包括“锁文件”--这就像一般的虚拟文件,为每个请求生成了名称。
一旦用户请求打开自定义协议,就会在服务器上专门为该协议打开请求生成这样的文件。
我在放置这些文件的服务器上创建了一个名为"$locks“的文件夹。一旦与协议相关的程序退出,相应的文件将被删除.
该网站继续使用XmlHttpRequest
检查请求的文件是否仍然存在,并在不存在的情况下触发回调(例如,测试之间的超时:1秒)。
新文件的结构如下:
lockThisRequest.php
:它基于$locks url参数在$locks目录中创建一个文件。unlockThisRequest.php
:它删除$locks目录中的一个文件;同样基于req
url参数。它的JavaScript部分是:
function launchCgit(params,callback)
{
var lock = /* Generate valid filename from params variable */;
// "Lock" that Request (means: telling the server that a request with this ID is now in use)
var locker = new XmlHttpRequest();
locker.open('GET', 'lockThisRequest.php?req='+lock, true)
locker.send(null);
function retry()
{
// Test if the lock-file still exists on the server
var req = new XmlHttpRequest();
req.open('GET', '$locks/'+lock, true);
req.onReadyStateChanged=function()
{
if (req.readyState == 4)
{
if (req.status == 200)
{
// lock-file exists -> cgit has not exited yet
window.setTimeout(retry,1000);
}
else if (req.status == 404)
{
// lock-file not found -> request has been proceeded
callback();
}
}
}
req.send(null);
}
document.location = 'cgit:'+params; // execute custom protocol
retry(); // initialize lockfileCheck-loop
}
乌萨奇是:
launchCgit("doThisAndThat",function()
{
alert("ThisAndThat finished.");
});
lockThisRequest.php
-file:
<?php
file_put_contents("$locks/".$_GET["req"],""); // Create lock file
?>
和unlockThisRequest.php
<?php
unlink("../\$locks/".$_GET["req"]); // Delete lock file
?>
协议执行的本地程序/脚本只需调用以下内容:
#!/bin/bash
curl "http://servername/unlockThisRequest.php?req=$1"
在它完成之后。
就像我刚才说的,这是可行的,但这不是什么好事(恭喜你,如果你跟踪那些指示)
我更喜欢一种更简单的方法,(重要的)这也可能会导致lockThisRequest.php
和unlockThisRequest.php
文件的安全性问题!
我对这个解决方案没意见,因为我只在一个受密码保护的私有页面上使用它。但是,如果您计划在公共或非受保护的页面上使用它,您可能需要向php文件添加一些安全性。
无论如何,这个解决方案现在对我有用,但是如果有人找到了更好的方法--例如通过使用ajax请求--他/她将非常欢迎以这种方式添加到相应的堆栈溢出文档或类似的文档中,并在这个线程上发布到它的链接。我仍然对其他解决方案感兴趣:)
发布于 2016-08-12 08:36:25
由于这并不是对window.location的预期使用,所以我会怀疑是否有一种简单的方法。我的建议是使用AJAX请求,并让c++程序在完成时发送响应。这样,任何在c++程序之后运行的代码都可以在请求完成时运行。
https://stackoverflow.com/questions/38906948
复制