javascript - 如何从 Javascript 启动两个或多个自定义 URL 协议(protocol)

标签 javascript html onclick url-protocol

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

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

我正在尝试修改它并使其也可以从其他浏览器使用。如果您知道答案,请停止阅读并回答。如果没有快速答案,这里是我尝试的描述。我成功地完成了这项工作,但仅限于脚本少于 2000 个字符的情况。我需要有关超过 2000 个字符的脚本的帮助。

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

我创建了我的 custom URL Protocol像这样启动一个 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 协议(protocol)将超过 2000 个字符传递给 VBScript 脚本?

如果不是,是否可以按顺序调用多个自定义 URL 协议(protocol)?

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

编辑 1

我找到了一个解决方案,但在 Chrome 中只在它喜欢的时候工作,所以我又回到了原点。

下面的代码在 IE 中执行脚本 4 次(正确),但在 Chrome 中只运行第一次执行。

如果我把它改成 delay += 2000 ,那么 Chrome 通常会运行脚本 2 次,但有时会运行 1 次,有时会运行 3 次甚至 4 次。

如果我把它改成 delay += 10000 ,然后它通常会运行脚本 4 次,但有时会错过一次。

该函数始终执行 4 次,无论是在 Chrome 还是 IE 中。奇怪的是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

我尝试了卢克的建议,即从回调内部设置下一次超时,但没有任何改变(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 服务器提供的,它甚至无法管理如此复杂的脚本。

最佳答案

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

我也希望自定义 url 协议(protocol)可以处理长 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.

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

更新:

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

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

假设您想要一个自定义 url 将 pdf 打印到默认打印机,而没有烦人的弹出窗口。我们每天需要这样做数千次......
  • 构建网页时,添加打印按钮,按下时调用自定义url:myproto://printpdf?id=12345&tocken=onetimetoken
  • 这将在本地桌面上执行您的 vbscript
  • 在您的 vbscript 中,解析参数并使用react。在这种情况下,您的命令是 printpdf 并且 id 是 123456 并且您有一个一次性 token key 。
  • 将 vb 脚本转到 https 获取:https://mydomain.com/APIs/printpdf.whatever?id=12345&key=onetimetoken
  • 根据 ip 地址和 token 检查凭据,如果全部对齐,则返回 pdf 的内容(您可能希望将 pdf 转换为字节数组字符串)
  • 现在 vbscript 有 pdf,组装它并将其写入临时文件夹,然后执行无提示 pdf 打印命令(我使用 Sumatra PDF http://blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader.html)
  • 任务完成。

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

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

    如果需要,您可以编写自定义 url 协议(protocol)来打开比萨 toastr :)

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

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

    更新 2:

    由于在这种情况下数据在客户端上(一个表单可以定义数百个参数),服务器 API 不知道如何响应 vb 脚本请求。所以上面描述的工作流之前必须有以下两个步骤:
  • onkeypress 事件执行提交将当前参数发送到服务器
  • 服务器用刷新后的表单回复,向主体 onload 添加对函数的调用,该函数使用另一个提交来调用自定义 url,如上面列出的第 1 点所述。

  • 更新 3:
    stenci,您添加的内容(在更新 2 中)将起作用。我会这样做:
  • 用户按下按钮说我已完成编辑表单
  • ajax 将表单发布到服务器
  • 服务器保存数据并将唯一 key 附加到数据存储区
  • 服务器返回键给ajax回调函数
  • 现在客户端有一个一次性使用的 key 并调用传递 key
  • 的 url 模式
  • vbscript 执行 https 访问服务器并传递 key
  • 服务器返回数据给vbscript

  • 有点啰嗦。一旦编码,它将像魅力一样工作。

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

    然后在 vbscript 中查看您是否可以阅读剪贴板,例如:Use clipboard from VBScript

    关于javascript - 如何从 Javascript 启动两个或多个自定义 URL 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23096887/

    相关文章:

    Javascript - 静态方法和实例方法的名称相同不好的做法?

    javascript - 如果其中一个子菜单项处于事件状态,则展开下拉菜单

    html - 如何使 li 元素从底部增长(类似于定位绝对底部)

    javascript 将文本输入传递给 onclick 处理程序

    javascript - 单击按钮不会触发JavaScript函数

    javascript - namespace 对象如何在 JavaScript 中与 AMD 一起使用?

    javascript - 如何向 Ember 中的提交操作添加参数?

    javascript - CSS/HTML double font color into a SELECT OPTION

    html - 没有拉伸(stretch)或重复的完整图像,具有高质量像素

    javascript onclick 按钮在单击时不起作用