2016-08-11 76 views
0

我有一个自定义URL协议处理程序cgit:[...]如何让JS等到协议执行完毕

它启动了一个后台进程,其配置在本地机器上的一些东西。该协议工作正常,我从JavaScript启动它(目前使用document.location = 'cgit:[...]'),但我真的希望JavaScript等到相关程序退出。


所以基本上我想要的JavaScript做的步骤:

  1. 的JavaScript做一些事情

  2. 的JavaScript推出cgit:[...]

  3. 的Javascript等待cgit:[...]退出

  4. 的JavaScript做别的事情


代码:

function launchCgit(params) 
{ 
    showProgressBar(); 
    document.location="cgit:"+params; 
    document.addEventListener(/* CGit-Program exited event */, hideProgressBar); 
} 

或:

function launchCgit(params) 
{ 
    showProgressBar(); 
    // setLocationAndWait("cgit:"+params); 
    hideProgressBar(); 
} 

这是可能的任何想法?

+0

添加一些代码可能有助于回答问题。 – c0d3rman

+0

好的,我将在 –

+0

中编辑一些cgit:要启动的是什么? – matmo

回答

1

,因为我没有找到使用AJAX请求或任何类似,我使用了一种-的丑workarround包括XmlHttpRequest


对于启动协议终于解决了我的问题解决我的问题以适当的方式我仍然在使用document.location=cgit:[...]

我正在使用包含“锁定文件”的服务器端系统 - 这就像通用虚拟文件,并为每个请求生成名称。

一旦用户请求打开自定义协议,就会在服务器上专门为该协议打开请求生成这样的文件。

我在放置这些文件的服务器上创建了一个名为“$ locks”的文件夹。一旦与协议相关的程序退出,相应的文件将被删除。

网站持续检查使用XmlHttpRequest的请求文件是否仍然存在,如果没有(例如测试之间的测试时间:1秒)则触发回调。

新文件的结构如下:

  • lockThisRequest.php:它的基础上,req网址参数的$锁目录中创建一个文件。
  • 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 
} 

Ussage是:

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.phpunlockThisRequest.php文件的安全问题!

我很好用这个解决方案,因为我只在受密码保护的私人页面上使用它。但是,如果您打算在公共或不受保护的页面上使用它,您可能需要为php文件添加一些安全性。


不管怎么说,该解决方案现在对我的作品,但如果有人找到更好的方式来做到这一点 - 通过使用Ajax请求 - 例如,他/她会很欢迎这种方式添加到相应的stackoverflow-文档或类似内容,并在此主题上发布链接。我仍然对替代解决方案感兴趣:)

1

因为这不是真正的预期的window.location使用,我怀疑有一个简单的方法。我的建议是使用AJAX请求,并让C++程序在完成时发送响应。这样,在请求完成后,可以运行C++程序之后,无论需要运行哪些代码。