Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I execute Javascript in my Delphi program without TWebBrowser?

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?

like image 896
Salvador Avatar asked Dec 12 '10 21:12

Salvador


People also ask

How do I execute JavaScript code?

To execute JavaScript in a browser you have two options — either put it inside a script element anywhere inside an HTML document, or put it inside an external JavaScript file (with a . js extension) and then reference that file inside the HTML document using an empty script element with a src attribute.

Do we need any software to run JavaScript?

Most likely, you'll find your JavaScript editor of choice in Sublime Text, Visual Studio Code, or Brackets. But several other tools—Atom, BBEdit, Notepad++, Emacs, and Vim—all have something to recommend them. Depending on the task at hand, you might find any one of them handy to have around.


2 Answers

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.

like image 94
Wouter van Nifterick Avatar answered Sep 20 '22 08:09

Wouter van Nifterick


SpiderMonkey

V8

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

like image 24
Ignacio Vazquez-Abrams Avatar answered Sep 20 '22 08:09

Ignacio Vazquez-Abrams