从Delphi程序调用Javascript函数

时间:2015-03-06 08:48:02

标签: javascript delphi

我有一个问题,我无法找到明确答案......

所以我有这个JavaScript代码:

var asp = {
    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
    lookup: null,
    ie: /MSIE/.test(navigator.userAgent),           // Checks the browser client
    ieo: /MSIE[67]/.test(navigator.userAgent),      // Checks The Browser Client
    encode: function(s) {
        var buffer = asp.toUtf8(s),
            position = -1,
            len = buffer.length,
            nan0, nan1, nan2, enc = [, , , ];
        if (asp.ie) {
            var result = [];
            while (++position < len) {
                nan0 = buffer[position];
                nan1 = buffer[++position];
                enc[0] = nan0 >> 2;
                enc[1] = ((nan0 & 3) << 4) | (nan1 >> 4);
                if (isNaN(nan1)) enc[2] = enc[3] = 64;
                else {
                    nan2 = buffer[++position];
                    enc[2] = ((nan1 & 15) << 2) | (nan2 >> 6);
                    enc[3] = (isNaN(nan2)) ? 64 : nan2 & 63
                }
                result.push(asp.alphabet.charAt(enc[0]), asp.alphabet.charAt(enc[1]), asp.alphabet.charAt(enc[2]), asp.alphabet.charAt(enc[3]))
            }
            return result.join('')
        } else {
            var result = '';
            while (++position < len) {
                nan0 = buffer[position];
                nan1 = buffer[++position];
                enc[0] = nan0 >> 2;
                enc[1] = ((nan0 & 3) << 4) | (nan1 >> 4);
                if (isNaN(nan1)) enc[2] = enc[3] = 64;
                else {
                    nan2 = buffer[++position];
                    enc[2] = ((nan1 & 15) << 2) | (nan2 >> 6);
                    enc[3] = (isNaN(nan2)) ? 64 : nan2 & 63
                }
                result += asp.alphabet[enc[0]] + asp.alphabet[enc[1]] + asp.alphabet[enc[2]] + asp.alphabet[enc[3]]
            }
            return result
        }
    },
    wrap: function(s) {
        if (s.length % 4) throw new Error("InvalidCharacterError: 'asp.wrap' failed: The string to be wrapd is not correctly encoded.");
        var buffer = asp.fromUtf8(s),
            position = 0,
            len = buffer.length;
        if (asp.ieo) {
            var result = [];
            while (position < len) {
                if (buffer[position] < 128) result.push(String.fromCharCode(buffer[position++]));
                else if (buffer[position] > 191 && buffer[position] < 224) result.push(String.fromCharCode(((buffer[position++] & 31) << 6) | (buffer[position++] & 63)));
                else result.push(String.fromCharCode(((buffer[position++] & 15) << 12) | ((buffer[position++] & 63) << 6) | (buffer[position++] & 63)))
            }
            return result.join('')
        } else {
            var result = '';
            while (position < len) {
                if (buffer[position] < 128) result += String.fromCharCode(buffer[position++]);
                else if (buffer[position] > 191 && buffer[position] < 224) result += String.fromCharCode(((buffer[position++] & 31) << 6) | (buffer[position++] & 63));
                else result += String.fromCharCode(((buffer[position++] & 15) << 12) | ((buffer[position++] & 63) << 6) | (buffer[position++] & 63))
            }
            return result
        }
    },
    toUtf8: function(s) {
        var position = -1,
            len = s.length,
            chr, buffer = [];
        if (/^[\x00-\x7f]*$/.test(s))
            while (++position < len) buffer.push(s.charCodeAt(position));
        else
            while (++position < len) {
                chr = s.charCodeAt(position);
                if (chr < 128) buffer.push(chr);
                else if (chr < 2048) buffer.push((chr >> 6) | 192, (chr & 63) | 128);
                else buffer.push((chr >> 12) | 224, ((chr >> 6) & 63) | 128, (chr & 63) | 128)
            }
        return buffer
    },
    fromUtf8: function(s) {
        var position = -1,
            len, buffer = [],
            enc = [, , , ];
        if (!asp.lookup) {
            len = asp.alphabet.length;
            asp.lookup = {};
            while (++position < len) asp.lookup[asp.alphabet.charAt(position)] = position;
            position = -1
        }
        len = s.length;
        while (++position < len) {
            enc[0] = asp.lookup[s.charAt(position)];
            enc[1] = asp.lookup[s.charAt(++position)];
            buffer.push((enc[0] << 2) | (enc[1] >> 4));
            enc[2] = asp.lookup[s.charAt(++position)];
            if (enc[2] == 64) break;
            buffer.push(((enc[1] & 15) << 4) | (enc[2] >> 2));
            enc[3] = asp.lookup[s.charAt(++position)];
            if (enc[3] == 64) break;
            buffer.push(((enc[2] & 3) << 6) | enc[3])
        }
        return buffer
    }
};

这是我的PC上的本地JavaScript文件,我需要能够从我的Delphi程序中调用它的函数(并接收函数的输出)...什么是最简单的实现方法这个?我在堆栈溢出时找到了一些源代码,但项目不完整,我无法使用包含的脚本,另一种方法是在两者之间创建一个中介(也许就像一个网页?)但我最好保持解决方案为尽可能简单,所以如果你们能帮我解决这个问题,我将非常感激!

对于好奇:上面的脚本是加密和解密算法 编辑:它不是一个加密算法,独立一个简单的base64编码器,因此这个问题已经解决了!

感谢您花时间阅读此内容,干杯现在!

2 个答案:

答案 0 :(得分:5)

该代码期望在浏览器环境中运行,因此要直接使用它,您必须在浏览器中运行它,也许是无头浏览器。虽然有可能删除它的浏览器特定部分,这似乎是Internet Explorer问题的解决方法。

我没有尝试直接使用它,而是非常复杂,我只是将它翻译成Delphi。

答案 1 :(得分:-3)

对于运行JavaScript函数,您必须使用WebBrowser组件(如TWebBrowser)。但是,默认情况下,TWebBrowser组件与最旧版本的Internet Explorer兼容。在第一步中,您必须兼容最新版本。为此,您必须使用此代码(适用于IE10):

procedure TForm1.btnIE10EmulatorClick(Sender: TObject);var
  RegObj: TRegistry;
begin
  RegObj := TRegistry.Create;
  try
    RegObj.RootKey := HKEY_LOCAL_MACHINE;
    RegObj.Access := KEY_ALL_ACCESS;


    if (TOSVersion.Architecture = arIntelX64) then
    begin
      RegObj.OpenKey('\SOFTWARE\Wow6432Node\Microsoft\Internet ' +
        'Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION', True);
    end
    else if (TOSVersion.Architecture = arIntelX86) then
    begin
      RegObj.OpenKey('\SOFTWARE\Microsoft\Internet ' +
        'Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION', True);
    end;


    RegObj.WriteInteger(ExtractFileName(Application.ExeName), 10000 {compatibility with IE10}); // for other versions read msdn
  finally
    RegObj.Free;
  end;
end;

在第二步中,在表单上放置一个TWebBrowser组件。

下一步,在您的应用中添加此功能:

procedure ExecuteJavaScript(document:IHTMLDocument2; Code: string);
var
  Window:IHTMLWindow2;
begin
  if not Assigned(Document) then Exit;
  Window:=Document.parentWindow;
  if not Assigned(Window) then Exit;
  try
    Window.execScript(Code,'JavaScript');
  except
    on E:Exception do raise Exception.Create('Javascript error '+E.Message+' in: '#13#10+Code);
  end;
end;

通过此功能,您可以运行javascript函数。

示例1(没有返回值的运行函数):

ExecuteJavaScript((WebBrowser1.Document as IHTMLDocument2), 'JsFunctionName();');

Example2(javascript代码返回值): 如果您的JS代码返回值,请将此函数添加到您的delphi程序中:

function GetElementIdValue(WebBrowser:TWebBrowser; TagName,TagId,TagAttrib:String):String;
var
  Document: IHTMLDocument2;
  Body: IHTMLElement2;
  Tags: IHTMLElementCollection;
  Tag: IHTMLElement;
  I: Integer;
begin
  Result:='';
  if not Supports(WebBrowser.Document, IHTMLDocument2, Document) then
    raise Exception.Create('Invalid HTML document');
  if not Supports(Document.body, IHTMLElement2, Body) then
    raise Exception.Create('Can''t find <body> element');
  Tags := Body.getElementsByTagName(UpperCase(TagName));
  for I := 0 to Pred(Tags.length) do begin
    Tag:=Tags.item(I,EmptyParam) as IHTMLElement;
    if Tag.id=TagId then Result:=Tag.getAttribute(TagAttrib,0);
  end;
end;

并使用此代码返回值:

procedure TForm1.Button3Click(Sender: TObject);
begin
  // eval demo cpde
  try
    ExecuteJavaScript(WebBrowser1,'DoEval("'+Edit1.Text+'");');
    ResultLabel.Caption := GetElementIdValue(WebBrowser1,'input','result','value'));
  except
    on E:Exception do ConsoleRed(E.Message);
  end;
end;

此示例中的JavaScript代码为:

function DoEval(expr){
 // eval for delphi!
 document.getElementById('result').value=eval(expr);
}

对于使用此示例,您的使用clouse必须如下:

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, OleCtrls, ExtCtrls, {REQUIRED UNITS} SHDocVw, MSHTML,
  ComCtrls {/REQUIRED UNITS};
相关问题