javascriptcustom-url-protocol

How to make JS wait until protocol execution finished


I have a custom URL protocol handler cgit:[...]

It launches up a background process which configures some stuff on the local machine. The protocol works fine, i'm launching it from JavaScript (currently using document.location = 'cgit:[...]'), but i actually want JavaScript to wait until the associated program exits.


So basically the steps i want JavaScript to do:

  1. JavaScript does something

  2. JavaScript launches cgit:[...]

  3. Javascript waits until cgit:[...] exits

  4. JavaScript does something else


Code:

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

or:

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

Any ideas if this is possible?


Solution

  • As i didn't find a suitable way to solve my problem using ajax requests or anything similar, i finally solved my problem using a kind-of-ugly workarround including XmlHttpRequest


    For launching the protocol i'm still using document.location=cgit:[...]

    I'm using a server side system including "lock-files" - that's like generic dummy files, with generated names for each request.

    Once the user requests to open the custom protocol, such a file is being generated on the server specifically for that one protocol-opening-request.

    I created a folder called "$locks" on the server where these files are being placed in. Once the protocol-associated program exits, the appropriate file is being deleted.

    The website continuously checks if the file for a request still exists using XmlHttpRequest and fires a callback if it doesn't (example timout between tests: 1 sec).

    The structure of the new files is the following:

    The JavaScript part of it goes:

    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 is:

    launchCgit("doThisAndThat",function()
                               {
                                   alert("ThisAndThat finished.");
                               });
    

    the lockThisRequest.php-file:

    <?php
        file_put_contents("$locks/".$_GET["req"],""); // Create lock file
    ?>
    

    and unlockThisRequest.php:

    <?php
        unlink("../\$locks/".$_GET["req"]); // Delete lock file
    ?>
    

    The local program / script executed by the protocol can simply call something like:

    #!/bin/bash
    curl "http://servername/unlockThisRequest.php?req=$1"
    

    after it finished.


    As i just said this works, but it's anything else than nice (congratulations if you kept track of those instructions)

    I'd rather prefered a more simple way and (important) this also may cause security issues with the lockThisRequest.php and unlockThisRequest.php files!

    I'm fine with this solution, because i'm only using it on a password protected private page. But if you plan to use it on a public or non protected page, you may want to add some security to the php files.


    Anyways, the solution works for me now, but if anyone finds a better way to do it - for example by using ajax requests - he/she would be very welcome to add that way to the respective stackoverflow-documentation or the like and post a link to it on this thread. I'd still be interested in alternative solutions :)