15

I am working with a Web API that uses a Javascript interface to make requests, and the response is via a callback Javascript function. Is there a way to call Javascript code from Delphi without using a TWebBrowsercomponent?

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Salvador
  • 16,132
  • 33
  • 143
  • 245

4 Answers4

5

You can always run cscript.exe on windows machines.

Advantages:

  1. It's available on all default windows installs since windows 98.
  2. It's dead easy.
  3. No third-party Delphi components needed.
  4. No dll's + wrappers needed, so deployment is simple.

Disadvantages:

  1. You'll be spawning new processes. Starting cscript.exe on a web server feels wrong. I'm not sure what the security implications are.
  2. You don't have direct access to the internals of the scripting engine.

Example program (it's just a proof-of-concept.. there are probably better ways to do this):

program JsExample;    
{$APPTYPE CONSOLE}

uses Windows, IoUtils;

// start a new process
function RunProgram(const aProg, aParams: string; aHow2Show: Word; const aWaitTime: dword): boolean;
var LProcInfo: TProcessInformation; LStartUpInfo: TStartupInfo;
begin
  FillChar(LStartUpInfo, SizeOf(TStartupInfo), #0); FillChar(LProcInfo, SizeOf(TProcessInformation), #0);
  with LStartUpInfo do
  begin
    cb := SizeOf(LStartUpInfo);
    lpReserved := nil; lpDesktop := nil; lpTitle := nil; lpReserved2 := nil; cbReserved2 := 0;
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := aHow2Show;
  end;
  Result := CreateProcess(nil, PChar(aProg + ' ' + aParams), nil, nil, false, CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS, nil, nil, LStartUpInfo, LProcInfo);
  if Result then
    Result := WaitForSingleObject(LProcInfo.hProcess, aWaitTime) <> WAIT_FAILED;
end;

// run javascript code
procedure RunJs(const aJavaScript: String);
var LTmpFileName: String;
begin
  LTmpFileName := TPath.ChangeExtension(TPath.GetTempFileName, '.js');
  try
    TFile.WriteAllText(LTmpFileName, aJavaScript);
    RunProgram('cscript', '/NOLOGO "' + LTmpFileName + '"', SW_SHOWNORMAL, INFINITE);
  finally
    TFile.Delete(LTmpFileName);
  end;
end;



// main
begin

  // execute some stupid javascript sample code
  RunJs
  (
    'var Text="Hello from JavaScript!";' + // creating a js variable
    'for(var i=0;i<Text.length;i++)' +     // creating a js looop
    '  WScript.Echo(Text.charAt(i));'      // calling string.charAt() and print some stuff
  );

  ReadLn;    
end.

This method is really simple.. write the JavaScript to a file, then call cscript.exe with the filename as a parameter.

Wouter van Nifterick
  • 23,603
  • 7
  • 78
  • 122
4

SpiderMonkey

V8

No clue if any of this actually (still) works though.

Community
  • 1
  • 1
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
2

Are you looking for a JavaScript engine? There are some on the market, such as FastScript, and also I saw a Delphi wrapper for Windows Scripting Host (which has JavaScript support). Note, though, that if your scripts use web- and browser-related classes and functions, no engine except browser-based one will be able to offer them.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
0

Is there a way to call Javascript code from Delphi without using a TWebBrowsercomponent?

Yes, other way to use JavaScript wrapper for SpiderMonkey (FireFox) javascript engine.

http://code.google.com/p/delphi-javascript/

Required only 1 DLL. Compatible with XE2/XE4/XE5. Ready for x86 and x64 systems.

Usame sample: Can I execute a Javascript function inside Spidermonkey and get the return value?

Community
  • 1
  • 1
Zam
  • 2,880
  • 1
  • 18
  • 33