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

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

问题描述

我有一个旧的 html 页面,它创建一个脚本文件并使用:

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")

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

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.

该网页仅供内部使用,因此我可以轻松地在每台运行网络驱动器中的 VBScript 文件的计算机上创建自定义 URL 协议.

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.

我创建了启动 VBScript 文件的 自定义 URL 协议这个:

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

Windows Registry Editor Version 5.00

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

[HKEY_CLASSES_ROOTMyUrlProtocolDefaultIcon]
@="C:\Windows\System32\WScript.exe"

[HKEY_CLASSES_ROOTMyUrlProtocolshell]

[HKEY_CLASSES_ROOTMyUrlProtocolshellopen]

[HKEY_CLASSES_ROOTMyUrlProtocolshellopencommand]
@="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> 我看到两条消息,所以一切正常(用 Chrome 测试和 Windows 7 中的 IE.)

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.)

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

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

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.

所以我尝试将脚本的文本分割成小于 2000 个字符的块,并模拟对链接的多次点击,但只有第一次有效.

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.

所以我尝试使用 xmlhttp.open("GET","MyUrlProtocol:test",false);,但 Chrome 说 跨源请求仅支持 HTTP.

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

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

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

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

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

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

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

编辑 1

我找到了一个解决方案,但在 Chrome 中只有在它喜欢的时候才有效,所以我回到了原点.

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

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

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

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

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.

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

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

在 Chrome 和 IE 中,该函数总是执行 4 次.奇怪的是 sr.click() 有时什么都不做,函数继续执行.

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>

编辑 2

我尝试了 Luke 的建议,即从回调内部设置下一个超时,但没有任何改变(IE 始终有效,Chrome 随时可用).

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).

这是新代码:

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 并要求执行该脚本.

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.

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

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:

我也希望自定义 url 协议可以处理长 url.他们根本没有.IE 更糟糕,因为某些操作系统只接受 800 个字符.

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.

所以,解决方案如下:

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.

更新:

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

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.

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

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.

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

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. 在构建网页时,添加打印按钮,按下该按钮会调用自定义 url:myproto://printpdf?id=12345&token=onetimetoken

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

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

this will execute your vbscript on the local desktop

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

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.

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

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

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

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)

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

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)

任务完成.

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

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.

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

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.

如果你愿意,你可以编写一个自定义 url 协议来打开比萨烤箱 :)

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

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

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

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

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

更新 2:

由于在这种情况下数据在客户端上(一个表单可以定义数百个参数),服务器 API 不知道如何响应 vb 脚本请求.所以上面描述的工作流程之前必须有这两个步骤:

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. onkeypress事件执行提交将当前参数发送到服务器

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

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

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.

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

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

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

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

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

我能看到的唯一其他选择是将表单数据复制到剪贴板,使用类似:http://zeroclipboard.组织/

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

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

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

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

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