如何从Javascript启动两个或多个自定义URL协议 [英] How to start two or more custom URL Protocol from Javascript

查看:98
本文介绍了如何从Javascript启动两个或多个自定义URL协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个旧的html页面,该页面创建一个脚本文件并使用以下命令执行该文件:

fsoObject = new ActiveXObject("Scripting.FileSystemObject")
wshObject = new ActiveXObject("WScript.Shell")

我正在尝试对其进行修改,并使其在其他浏览器中也可以使用.如果您知道答案,请停止阅读,然后再回答.如果没有快速的答案,这是我的尝试的描述.我成功完成了这项工作,但是仅当脚本少于2000个字符时才这样做.对于超过2000个字符的脚本,我需要帮助.

该网页仅供内部使用,因此我很容易在每台从网络驱动器运行VBScript文件的计算机上创建自定义URL协议.

我创建了自定义URL协议,该文件启动了VBScript文件,例如这个:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\MyUrlProtocol]
"URL Protocol"=""
@="Url:MyUrlProtocol"
"UseOriginalUrlEncoding"=dword:00000001

[HKEY_CLASSES_ROOT\MyUrlProtocol\DefaultIcon]
@="C:\\Windows\\System32\\WScript.exe"

[HKEY_CLASSES_ROOT\MyUrlProtocol\shell]

[HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open]

[HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open\command]
@="C:\\Windows\\System32\\WScript.exe \"X:\\MyUrlProtocol.vbs\" \"%1\""

MyUrlProtocol.vbs中,我有这个:

MsgBox "The length of the link is " & Len(WScript.Arguments(0)) & " characters"
MsgBox "The content of the link is: " & WScript.Arguments(0)

当我单击<a href="MyUrlProtocol:test" id="test">click me</a>时,我看到两条消息,因此一切正常(在Windows 7中经过Chrome和IE测试).

当我执行document.getElementById("test").click()

时,它也起作用

我认为这可能是解决方案:我会将脚本文本传递给VBS静态脚本,该脚本将创建动态脚本并运行它,但是使用此系统,我不能传递超过2000个字符.

因此,我尝试将脚本的文本拆分为小于2000个字符的小块,并模拟对链接的多次单击,但只有第一个有效.

所以我尝试使用xmlhttp.open("GET","MyUrlProtocol:test",false);,但是Chrome说Cross origin requests are only supported for HTTP.

是否可以通过自定义URL协议将超过2000个字符传递给VBScript脚本?

如果没有,是否可以依次调用多个自定义URL协议?

如果没有,是否还有另一种方法来创建脚本文件并从Javascript运行它?

编辑1

我找到了一个解决方案,但是在Chrome中,只有在喜欢的时候它才能工作,所以我回到正题.

以下IE中的代码将执行脚本4次(正确),但在Chrome中仅运行第一次执行.

如果我将其更改为delay += 2000,则Chrome通常会运行脚本2次,但有时会运行1次,有时甚至是3次甚至4次.

如果我将其更改为delay += 10000,则它通常会运行脚本4次,但有时会丢失一次.

该功能始终在Chrome和IE中执行4次.奇怪的是,sr.click()有时什么也不做,并且函数继续执行.

<HTML>
<HEAD>
  <script>
    var delay;

    function runScript(text) {
      setTimeout(function(){runScript2(text)}, delay);
      delay += 100;
    }

    function runScript2(text) {
      var sr = document.getElementById('scriptRunner');
      sr.href='intelliclad:'+text;
      sr.click();
    }

    function test(){
      delay = 0;
      runScript("uno");
      runScript("due");
      runScript("tre");
      runScript("quattro");
    }
  </script>
</HEAD>
<BODY>
  <input type="button" value="Run test" onclick="test()">
  <a href="nothing yet" id="scriptRunner">scriptRunner</a>
</BODY>
</HMTL>

编辑2

我尝试了卢克(Luke)的建议,即从回叫中设置下一次超时,但是没有任何变化(IE始终有效,只要喜欢,Chrome就会起作用).

这是新代码:

var scripts;
var delay = 2000;

function runScript() {
  var sr = document.getElementById('scriptRunner');
  sr.href = 'intelliclad:' + scripts.shift();
  sr.click();

  if(scripts.length)
    setTimeout(function() {runScript()}, delay);
}

function test(){
  scripts = ["uno", "due", "tre", "quattro"];
  runScript();
}

某些背景:页面要求面板的形状,可以只是几个参数[nfaces=1, shape1='square', width1=100]或具有许多面,许多插槽,许多紧固件等的面板的数百个参数.在询问了所有参数之后会为我们的内部3D CAD(可能大于20KB)生成一个脚本,并启动CAD并要求执行该脚本.

我想在客户端上做所有事情,因为该页面由Domino Web服务器提供服务,它甚至无法梦想管理如此复杂的脚本.

解决方案

我没有阅读您的整个帖子...得到了答案:

我也希望自定义网址协议可以处理长网址.他们根本不这样做. IE更加糟糕,因为某些操作系统只接受800个字符.

所以,这是解决方法:

For long urls, only pass a single use token.   The vbscript uses the token 
and does a url get to your web server to get all of the data.

这是我能够成功传递大量数据的唯一方法.如果您找到更清晰的解决方案,请记住在此处发布.

更新:

请注意,这是我发现解决url协议限制的最佳方法.我也希望这是没有必要的.这确实行得通,而且效果很好.

您提到了Domino,因此可能在POS环境中需要一些东西...我创建了一个基于Web的POS系统,因此我们可能会遇到很多相同的问题.

假设您要一个自定义URL将pdf打印到默认打印机,而没有烦人的弹出窗口.我们每天需要做数千次……

  1. 在构建网页时,添加打印按钮,按下该按钮会调用自定义网址:myproto://printpdf?id = 12345& tocken = onetimetoken

  2. 这将在本地桌面上执行您的vbscript

  3. 在vbscript中
  4. 解析参数并做出反应.在这种情况下,您的命令是printpdf,id为123456,并且具有一次性密钥.

  5. 已将vb脚本添加到https,请访问: https://mydomain.com/APIs/printpdf.whatever?id=12345&key=onetimetoken

  6. 根据IP地址和令牌检查凭据,如果全部对齐,则返回pdf的内容(您可能希望将pdf转换为字节数组字符串)

  7. 现在vbscript具有pdf,将其组装并将其写入临时文件夹,然后执行无声pdf打印命令(我使用Sumatra PDF http://zeroclipboard. org/

    ,然后在vbscript中查看是否可以读取剪贴板,例如:使用VBScript中的剪贴板

    I have an old html page that creates a script file and executes it using:

    fsoObject = new ActiveXObject("Scripting.FileSystemObject")
    wshObject = new ActiveXObject("WScript.Shell")
    

    I am trying to modify it and make it usable also from other browsers. If you know the answer stop reading and please answer. If there is no quick answer, here is the description of my attempts. I was successful in doing the job, but only when the script is shorter than 2000 characters. I need help for scripts longer than 2000 characters.

    The webpage is for internal use only, so it is easy for me to create a custom URL protocol on each computer that runs a VBScript file from a network drive.

    I created my custom URL Protocol that starts a VBScript file like this:

    Windows Registry Editor Version 5.00
    
    [HKEY_CLASSES_ROOT\MyUrlProtocol]
    "URL Protocol"=""
    @="Url:MyUrlProtocol"
    "UseOriginalUrlEncoding"=dword:00000001
    
    [HKEY_CLASSES_ROOT\MyUrlProtocol\DefaultIcon]
    @="C:\\Windows\\System32\\WScript.exe"
    
    [HKEY_CLASSES_ROOT\MyUrlProtocol\shell]
    
    [HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open]
    
    [HKEY_CLASSES_ROOT\MyUrlProtocol\shell\open\command]
    @="C:\\Windows\\System32\\WScript.exe \"X:\\MyUrlProtocol.vbs\" \"%1\""
    

    In MyUrlProtocol.vbs I have this:

    MsgBox "The length of the link is " & Len(WScript.Arguments(0)) & " characters"
    MsgBox "The content of the link is: " & WScript.Arguments(0)
    

    When I click on <a href="MyUrlProtocol:test" id="test">click me</a> I see two messages, so everything works well (tested with Chrome and IE in Windows 7.)

    It works also when I execute document.getElementById("test").click()

    I thought this could be the solution: I would pass the text of the script to the VBS static script, which would create the dynamic script and run it, but with this system I can't pass more than ~2000 characters.

    So I tried to split the text of the script in chunks smaller than 2000 characters and simulate several clicks on the link, but only the first one works.

    So I tried with xmlhttp.open("GET","MyUrlProtocol:test",false);, but Chrome says Cross origin requests are only supported for HTTP.

    Is it possible to pass more than 2000 characters to a VBScript script via a custom URL protocol?

    If not, is it possible to call several custom URL protocols in sequence?

    If not, is there another way to create a script file and run it from Javascript?

    EDIT 1

    I found a solution, but in Chrome only works when it likes, so I'm back to square one.

    The code below in IE executes the script 4 times (correct), but in Chrome only the first execution runs.

    If I change it to delay += 2000, then Chrome usually runs the script 2 times, but sometimes 1 and sometimes 3 or even 4 times.

    If I change it to delay += 10000, then it usually runs the script 4 times, but sometimes misses one.

    The function is always executed 4 times, both in Chrome and IE. What is weird is that the sr.click() sometimes does nothing and the function execution continues.

    <HTML>
    <HEAD>
      <script>
        var delay;
    
        function runScript(text) {
          setTimeout(function(){runScript2(text)}, delay);
          delay += 100;
        }
    
        function runScript2(text) {
          var sr = document.getElementById('scriptRunner');
          sr.href='intelliclad:'+text;
          sr.click();
        }
    
        function test(){
          delay = 0;
          runScript("uno");
          runScript("due");
          runScript("tre");
          runScript("quattro");
        }
      </script>
    </HEAD>
    <BODY>
      <input type="button" value="Run test" onclick="test()">
      <a href="nothing yet" id="scriptRunner">scriptRunner</a>
    </BODY>
    </HMTL>
    

    EDIT 2

    I tried with Luke's suggestion of setting the next timeout from inside the call back but nothing changed (IE works always, Chrome whenever it likes).

    Here is the new code:

    var scripts;
    var delay = 2000;
    
    function runScript() {
      var sr = document.getElementById('scriptRunner');
      sr.href = 'intelliclad:' + scripts.shift();
      sr.click();
    
      if(scripts.length)
        setTimeout(function() {runScript()}, delay);
    }
    
    function test(){
      scripts = ["uno", "due", "tre", "quattro"];
      runScript();
    }
    

    Some background: The page asks for the shape of a panel, which can be just a few parameters [nfaces=1, shape1='square', width1=100] or hundreds of parameters for panels with many faces, many slots, many fasteners, etc. After asking for all the parameters a script for our internal 3D CAD (which can be larger than 20KB) is generated and the CAD is started and asked to execute the script.

    I would like to do all on the client side, because the page is served by a Domino web server, which can't even dream of managing such a complex script.

    解决方案

    I didn't read your whole post...have an answer:

    I too wish that custom url protocols can handle long urls. They simply do not. IE is even worse as some OSs only accept 800 chars.

    So, here's the solution:

    For long urls, only pass a single use token.   The vbscript uses the token 
    and does a url get to your web server to get all of the data.
    

    This is the only way I've been able to successfully pass lots of data around. If you ever find a clearer solution, please remember to post it here.

    Update:

    Note that this is the best way I have found to deal with the url protocol limitations. I too wish this was not necessary. This does work and works well.

    You mentioned Dominos, so possibly you need something in a POS environment... I create a web based POS system, so we could face a lot of the same issues.

    Suppose you want a custom url to print a pdf to the default printer without the annoying popup window. We need to do this thousands of times a day...

    1. When building the web page, add the print button which when pressed calls the custom url: myproto://printpdf?id=12345&tocken=onetimetoken

    2. this will execute your vbscript on the local desktop

    3. in your vbscript, parse the arguments and react. In this case, your command is printpdf and the id is 123456 and you have a onetime tocken key.

    4. have the vb script to an https get to: https://mydomain.com/APIs/printpdf.whatever?id=12345&key=onetimetoken

    5. check the credentials based on the ip address and token, if all aligns, then return the contents of the pdf (you may want to convert the pdf to a byte array string)

    6. now the vbscript has the pdf, assemble it and write it to a temp folder then execute a silent pdf print command (I use Sumatra PDF http://blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader.html)

    7. mission accomplished.

    Since I do know what you what to do in your custom url and the general workflow, I can only describe how I've solved the sort url issue.

    Using this technique, the possibilities are limitless. You have full control over the local computer running the web browser, you have a onetime use token which grants access to a web API with can return any sort of information you program.

    You could write a custom url protocol to turn on the pizza oven if you wanted :)

    If you are not able to create the server side code which is listening for vbscript's get request then this would not work.

    You might be able to pass the data from the browser to the vbscript using the clipboard.

    Update 2:

    Since in this case the data is on the client (one single form can define hundreds of parameters), the server API doesn't know what to answer to the vb script request. So the workflow described above must be preceded by these two steps:

    1. The onkeypress event executes a submit to send the current parameters to the server

    2. The server replies with the refreshed form, adding to the body onload a call to a function which uses another submit to call the custom url, as described on point 1 listed above.

    Update 3: stenci, what you've added (in Update 2) will work. I would do it like this:

    1. user presses a button saying I'm done editing the form
    2. ajax post the form to the server
    3. the server saves the data and attaches unique key to the datastore
    4. the server returns the key to ajax callback function
    5. now the client has a single use key and invokes the url schema passing the key
    6. vbscript does an https get to the server and passes the key
    7. server returns the data to the vbscript

    It is a bit long winded. Once coded it will work like a charm.

    The only other alternative I can see is to copy the form data to the clipboard using something like: http://zeroclipboard.org/

    and then in vbscript see if you can read the clipboard like: Use clipboard from VBScript

    这篇关于如何从Javascript启动两个或多个自定义URL协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆