我有一个旧的html页面,它创建一个脚本文件并使用以下命令执行它:
fsoObject = new ActiveXObject("Scripting.FileSystemObject")
wshObject = new ActiveXObject("WScript.Shell")
我正在尝试修改它并使其也可以从其他浏览器使用。如果你知道答案停止阅读,请回答。如果没有快速回答,这里是我的尝试的描述。我成功地完成了这项工作,但只有当脚本短于2000个字符时才会这样做。我需要帮助超过2000个字符的脚本。
该网页仅供内部使用,因此我可以轻松地在从网络驱动器运行VBScript文件的每台计算机上创建自定义URL协议。
我创建了我的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协议将超过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服务器提供服务,甚至无法管理这样复杂的脚本。
答案 0 :(得分:4)
我没看完你的全部帖子......得到答案:
我也希望自定义网址协议可以处理长网址。他们根本就没有。 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协议限制的最佳方法。我也希望这不是必要的。这确实有效并且效果很好。
你提到了Dominos,所以你可能需要POS环境中的东西......我创建了一个基于Web的POS系统,所以我们可能面临很多相同的问题。
假设您想要一个自定义网址将pdf打印到默认打印机而不会出现恼人的弹出窗口。我们需要每天做成千上万次......
在构建网页时,添加打印按钮,按下时调用自定义网址:myproto:// printpdf?id = 12345&amp; tocken = onetimetoken
这将在本地桌面上执行您的vbscript
,解析参数并做出反应。在这种情况下,您的命令是printpdf,id是123456,并且您有一次性的tocken密钥。
将https的vb脚本转到:https://mydomain.com/APIs/printpdf.whatever?id=12345&key=onetimetoken
根据ip地址和令牌检查凭据,如果所有对齐,则返回pdf的内容(您可能希望将pdf转换为字节数组字符串)
现在vbscript有pdf,汇编它并将其写入临时文件夹然后执行一个无声的pdf打印命令(我使用苏门答腊PDF http://blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader.html)
任务完成。
由于我确实知道您在自定义网址和常规工作流程中要做什么,因此我只能说明我是如何解决排序网址问题的。
使用这种技术,可能性是无限的。您可以完全控制运行Web浏览器的本地计算机,您可以使用一次性使用令牌来授予对Web API的访问权限,并且可以返回您编写的任何类型的信息。
如果您愿意,可以编写自定义网址协议来打开比萨饼烤箱:)
如果您无法创建正在侦听vbscript的get请求的服务器端代码,那么这将无效。
您可以使用剪贴板将数据从浏览器传递到vbscript。
更新2:
由于在这种情况下数据在客户端上(一个表单可以定义数百个参数),因此服务器API不知道应该对vb脚本请求回答什么。因此,上述工作流程必须先执行以下两个步骤:
onkeypress
事件执行提交以将当前参数发送到服务器
服务器使用刷新的表单进行回复,向正文onload
添加对函数的调用,该函数使用另一个提交来调用自定义网址,如上面第1点所述。
更新3: stenci,您添加的内容(在Update 2中)将起作用。我会这样做:
有点长啰嗦。一旦编码,它将像魅力一样工作。
我能看到的唯一其他选择是使用以下内容将表单数据复制到剪贴板:http://zeroclipboard.org/
然后在vbscript中查看是否可以阅读剪贴板,如:Use clipboard from VBScript
答案 1 :(得分:2)
如何为每个实例创建iFrame? 像这样:
function runScript(text) {
var iframe = document.createElement('iframe');
iframe.src = 'intelliclad:'+text;
document.body.appendChild(iframe);
}
function test(){
runScript("uno");
runScript("due");
runScript("tre");
runScript("quattro");
}
然后,您可以使用CSS样式来使这些iframe透明/隐藏。
答案 2 :(得分:0)
你可能不喜欢这个答案,但我过去使用过这种方法并且有效。
不要依赖ActiveX,而应考虑使用Java Applet和JNI。
基本上,您必须确保要运行的本机脚本在客户端计算机上以及JNI包装器上可用。
applet必须至少是自签名的,浏览器允许它加载和访问本机库。加载JNI库后,您可以轻松地从页面/小程序中调用方法。
由于使用Java,您可以使用相同的applet用于Windows以及Linux客户端,前提是您在相应的客户端上都有本机库。
这一系列文章准确地讨论了您的问题:http://www.javaworld.com/article/2076775/java-security/escape-the-sandbox--access-native-methods-from-an-applet.html
P.S这篇文章真的很老了,但概念仍未改变。