Call a function written in VB from JScript code (classic ASP)

I currently have to deal with a legacy system written in VB. I am not good at VB and ASP, so I decided that the new code for this system would be written in JScript.

However, there is some problem with interoperability between the two languages: namely, when I try to call some function declared in the <script language="vbscript"> , it fails with the Object expected error (if the language of the page is VBScript) and vice versa.

Namely, the following code:

inc.asp

 <script language="vbscript" runat="server"> Sub VBTestFunction(Message) Response.Write "VBTestFunction: " & Message End Sub </script> <script language="javascript" runat="server"> function JSTestFunction(Message) { Response.Write("JSTestFunction: " + Message); } </script> 

testjs.asp

 <%@ Language="JavaScript" %> <!-- #include file="inc.asp"--> <script language="javascript" runat="server"> VBTestFunction("from javascript"); JSTestFunction("from javascript"); </script> <script language="vbscript" runat="server"> Call VBTestFunction("from vbscript") Call JSTestFunction("from vbscript") </script> 

The following error failed:

 VBTestFunction: from vbscript Microsoft VBScript runtime error '800a000d' Type mismatch: 'JSTestFunction' /test.asp, line 9 

(if I comment on a specific line, the other three statements will work fine); setting the page language to VBScript

 <%@ Language="VBScript" %> <!-- #include file="inc.asp"--> <script language="javascript" runat="server"> VBTestFunction("from javascript"); JSTestFunction("from javascript"); </script> <script language="vbscript" runat="server"> Call VBTestFunction("from vbscript") Call JSTestFunction("from vbscript") </script> 

The following error failed:

 Microsoft JScript runtime error '800a138f' Object expected /test.asp, line 4 

(again, if I comment on a specific line, the other three statements will work fine).

There is an article in the MSDN article about mixing VB and JS in one application, but from the article it seems that the sample code should work like TestFunction declared in another file and is a function in the end.

Is there a way to make it all work and call both VBTestFunction and JSTestFunction from VB and JS code? I assume that it should be alone, otherwise it would not make sense to mix JS and VB.

+6
vbscript asp-classic jscript
source share
3 answers

I watched this question for a while, and Salman answered it pretty well, but there are some things that can be clarified. First of all, there is a key problem with the link to the article. It says that the order of execution is as follows: -

1.Script in elements of insecure languages
2.Inline script
3.Script in default language elements

Wrong, or at least its deprecated (it does after all IIS4 references). An "inline script" (that is, a script in the default language) is not processed differently than script elements of the same language.

Here's how to talk about what's going on.

  • Before starting any parsing, all included points are resolved and replaced with contents from the included files to create one lexical β€œfile”. This is created before the parsing happens.

  • Script code is collected from this "file" for each language. You can submit several files (one per language) that will be added to each fragment found. Please note that this is the reason that <script runat="server" <% %> and <script runat="server" for the default language are practically unresponsive.

  • Any static content (content outside the runat="server" script tag or <% %> %% <% %> ) is considered part of the default language code. The special Response.Write form, which sends static bytes of content in response, is created and added to the default language code in the place that it was found in the source file.

  • We now have one or more scripts ready to be processed by their respective script engines. Unused language scripts are parsed and executed . Any global identifier is created, whether it be a function or a variable, is added to the script environment. However, since the default language of the script was not processed at all, at this point nothing that it can subsequently add to the global script environment is not yet available.

  • By the time the default script language is parsed and executed, all global identifiers created by previous language scripts will be added to the script environment and therefore available for use from the built-in code.

It should be carefully noted that a language function can be called by a code in a function in a non-default language, provided that the non-default function call can be traced back to the line running the default language.

For example, if the default language is JScript , you can use the VBScript function (fnA) function declared in JScript (fnB) if the fnA call fnA executed as part of the built-in JScript execution. IOW JScript can invoke VBScript, which in turn can invoke VBScript, etc. The limiting factor is the engine that the top of this chain should be JScript in this script.

In your code example, you had code at the global (embedded) level of your VBScript trying to call a function declared in JScript by default. If you follow the marks above, you will see that at the point at which it is executed, the called function does not exist.

+6
source share

I urge you not to mix scripting languages. The article you talked about has a headline called "Server Script Execution Order," which says:

... However, you are at the mercy of the IIS ASP execution order. For example, if you create a Script server and run it in IIS 4.0 you will find this execution order:

  • Script in <SCRIPT> elements in underestimated languages.
  • Inline script
  • Script in <SCRIPT> elements in the default language

Keeping this in mind, here is how your testjs.asp Script is executed, comments indicate the order of execution:

 <%@ Language="JavaScript" %> <script language="vbscript" runat="server"> '' #1 Sub VBTestFunction(Message) Response.Write "VBTestFunction: " & Message End Sub </script> <script language="javascript" runat="server"> // #3 function JSTestFunction(Message) { Response.Write("JSTestFunction: " + Message); } </script> <script language="javascript" runat="server"> // #4 VBTestFunction("from javascript"); JSTestFunction("from javascript"); </script> <script language="vbscript" runat="server"> '' #2 Call VBTestFunction("from vbscript") Call JSTestFunction("from vbscript") </script> 

Notice the line that causes the error:

 Call JSTestFunction("from vbscript") 

Its execution order is # 2; at this point, the JSTestFunction function JSTestFunction not defined (it is defined later in execution order).

Now for the testvbs.asp file:

 <%@ Language="VBScript" %> <script language="vbscript" runat="server"> '' 3 Sub VBTestFunction(Message) Response.Write "VBTestFunction: " & Message End Sub </script> <script language="javascript" runat="server"> // 1 function JSTestFunction(Message) { Response.Write("JSTestFunction: " + Message); } </script> <script language="javascript" runat="server"> // 2 VBTestFunction("from javascript"); JSTestFunction("from javascript"); </script> <script language="vbscript" runat="server"> '' 4 Call VBTestFunction("from vbscript") Call JSTestFunction("from vbscript") </script> 

Error line:

 VBTestFunction("from javascript"); 

Again, the VBTestFunction is called before it is defined. The solution is to try not to mix scripting languages. If absolutely necessary, edit the order of your scripts.

Edit - Example

If you set @ Language="JavaScript" , then this code should work as expected:

 <!-- inc.asp--> <script language="vbscript" runat="server"> Sub VBTestFunction(Message) Response.Write "VBTestFunction: " & Message End Sub </script> <% function JSTestFunction(Message) { Response.Write("JSTestFunction: " + Message); } %> <!-- testjs.asp --> <%@ Language="JavaScript" %> <!-- #include file="inc.asp"--> <% // at this point, both functions are available VBTestFunction("from inline JavaScript"); JSTestFunction("from inline JavaScript"); %> 

If you want to use @ Language="VBScript" , you need to reorder all the code:

 <!-- inc.asp--> <script language="javascript" runat="server"> function JSTestFunction(Message) { Response.Write("JSTestFunction: " + Message); } </script> <% Sub VBTestFunction(Message) Response.Write "VBTestFunction: " & Message End Sub %> <!-- testvbs.asp --> <%@ Language="VBScript" %> <!-- #include file="inc.asp"--> <% ' at this point, both functions are available VBTestFunction("from inline VBScript") JSTestFunction("from inline VBScript") %> 
+2
source share

I don't know all the rules, but this works for me:

test.asp:

 <%@ language="JavaScript" %> <script language="VBScript" runat="server" src="mix2.vbs"></script> <script language="JavaScript" runat="server"> TestFunction("from javascript"); </script> 

mix2.vbs:

 Sub TestFunction (message) Response.Write message End Sub 

Note:

  • there is no <script> tag in the vbs file.
  • the tag <%@ language="..." %> at the top should indicate the "main" language. The <script> blocks that use the secondary language (in your case, VBScript) will then be interpreted and available to any code in the main language.

May be related: How can I use Javascript OO classes from VBScript in ASP-Classic or WSH?

0
source share

All Articles