如何从Javascript启动两个或多个自定义URL协议

ste*_*nci 10 html javascript onclick url-protocol

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

fsoObject = new ActiveXObject("Scripting.FileSystemObject")
wshObject = new ActiveXObject("WScript.Shell")
Run Code Online (Sandbox Code Playgroud)

我正在尝试修改它并使其也可以从其他浏览器使用.如果你知道答案停止阅读,请回答.如果没有快速回答,这里是我的尝试的描述.我成功地完成了这项工作,但只有当脚本短于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\""
Run Code Online (Sandbox Code Playgroud)

MyUrlProtocol.vbs我有这样的:

MsgBox "The length of the link is " & Len(WScript.Arguments(0)) & " characters"
MsgBox "The content of the link is: " & WScript.Arguments(0)
Run Code Online (Sandbox Code Playgroud)

当我点击时,<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>
Run Code Online (Sandbox Code Playgroud)

编辑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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

Bri*_*ity 4

我没有阅读你的整篇文章......有一个答案:

我也希望自定义 url 协议可以处理长 url。他们根本不知道。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.
Run Code Online (Sandbox Code Playgroud)

这是我能够成功传递大量数据的唯一方法。如果您找到更清晰的解决方案,请记得将其发布在这里。

更新:

请注意,这是我发现的处理 url 协议限制的最佳方法。我也希望这没有必要。这确实有效并且效果很好。

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

假设您想要一个自定义 url 来将 pdf 打印到默认打印机,而不需要烦人的弹出窗口。我们每天需要这样做数千次......

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

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

  3. 在你的 vbscript 中,解析参数并做出反应。在本例中,您的命令是 printpdf,id 是 123456,并且您有一个一次性令牌密钥。

  4. 将 vb 脚本连接到 https 访问: https://mydomain.com/APIs/printpdf.whatever?id=12345& key=onetimetoken

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

  6. 现在vbscript有pdf,组装它并将其写入临时文件夹,然后执行静默pdf打印命令(我使用Sumatra PDF http://blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader.html

  7. 任务完成。

由于我确实知道您在自定义 url 和一般工作流程中要做什么,所以我只能描述我如何解决排序 url 问题。

使用这种技术,可能性是无限的。您可以完全控制运行 Web 浏览器的本地计算机,您拥有一次性使用令牌,该令牌授予对 Web API 的访问权限,并且可以返回您编程的任何类型的信息。

如果您愿意,您可以编写自定义 url 协议来打开披萨烤箱:)

如果您无法创建侦听 vbscript 的 get 请求的服务器端代码,那么这将不起作用。

您也许可以使用剪贴板将数据从浏览器传递到 vbscript。

更新2:

由于在本例中数据位于客户端(一个表单可以定义数百个参数),因此服务器 API 不知道如何回答 vb 脚本请求。因此,上述工作流程必须先执行以下两个步骤:

  1. onkeypress事件执行一次提交,将当前参数发送到服务器

  2. 服务器使用刷新的表单进行回复,并向正文添加onload对函数的调用,该函数使用另一个提交来调用自定义 URL,如上面列出的第 1 点所述。

更新 3: stenci,您添加的内容(在更新 2 中)将起作用。我会这样做:

  1. 用户按下按钮说我已完成表单编辑
  2. ajax将表单发送到服务器
  3. 服务器保存数据并将唯一密钥附加到数据存储
  4. 服务器将key返回给ajax回调函数
  5. 现在客户端有一个单一使用密钥并调用传递该密钥的 url 模式
  6. vbscript 通过 https 访问服务器并传递密钥
  7. 服务器将数据返回给vbscript

说得有点啰嗦了。一旦编码,它就会像魅力一样发挥作用。

我能看到的唯一其他选择是使用以下内容将表单数据复制到剪贴板: http://zeroclipboard.org/

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