VBScript and JScript Don't Mix, at least in ASP

VBScript and JScript Don't Mix, at least in ASP

Rate This
  • Comments 15

A reader wrote me recently to describe a problem that I used to hear fairly often:

I write ASP code using VBScript and a coworker of mine uses JScript.  We were wondering if we could combine our code in ASP.  However, it does not seem to be working right.  Here is an example of where we are having trouble:

<SCRIPT LANGUAGE="JScript" RUNAT="Server">
Response.Write("<H1>header</H1>");
</SCRIPT>
<SCRIPT LANGUAGE ="VBScript" RUNAT="Server">
Response.Write "<H1>body</H1>"
</SCRIPT>
<SCRIPT LANGUAGE ="JScript" RUNAT="Server">
Response.Write("<H1>footer</H1>");
</SCRIPT>

As you can see this code should write:

header
body
footer

but the ASP engine does not render it like that.

My advice: don't mix languages on one ASP page because, as my correspondent discovered, it doesn't work the way you think it should.  The rendering comes all out of order.  Why?

Before you read on, if you don't understand the ASP compilation model you should read my earlier post on the subject.  To briefly recap, ASP translates the page into a script, sticks the script into an engine, and then clones the engine a bunch of times if it needs to.  Every time the page is served, the engine is pulled out of the engine pool, the script is run, and everything just works.

So what happens when you have two languages on the page?  You need two engines, but the mechanism is the same.  The page is compiled up into two scripts, and ASP runs one engine and then the other.

Now it should become clear why this appears to run out of order.  From ASP's perspective, the page above turns into two scripts:

// Jscript
Response.Write("<H1>header</H1>");
Response.Write("<H1>footer</H1>");

' VBScript
Response.Write "<H1>body</H1>"

The ASP engine does not maintain any information about which chunk should execute before another.  It gathers up all the script chunks for each language, compiles them, and then runs each engine in turn.  Not only does it lead to seemingly out-of-order execution as shown here, but it also restricts the language blocks from calling each other's methods (because the methods in the not-yet-executed block may not have been initialized yet.)  A detailed discussion of how IE solves this problem deserves another blog entry on its own.

Mixing languages can also lead to performance problems, because it means that each page is now consuming TWO engines from the engine cache, which means more cache misses, larger working set, etc.

While I'm on the subject, note that it is in general a bad idea to put a whole lot of "inline" code into <SCRIPT> blocks like that.  Ideally you want the server side <SCRIPT> blocks to contain only global function definitions, and the <% %> blocks to contain only "inline" code.  ASP does not enforce that constraint, but ASP.NET does.  (The reasoning behind that is long enough to require another post.)

If you really want to have multiple languages on one ASP page, here is a way you can make this work though if you really need to.  You could write a bunch of Windows Script Component objects in different languages, which expose methods.  You could then write an ASP page in one language that calls those methods in the right order.  WSCs are good in ASP because (a) they efficiently cache engine state, just like ASP, and (b) they can use the ASP object model directly if you write them correctly.

  • You can code functions in different languages.

    The order in which they are declared should not matter, only the order in which you call them.

  • I always thought that WSC's were dead; they proved to be a bad idea due to performance reasons?

    Either way, what about simply doing something along the lines of:

    <SCRIPT LANGUAGE="JScript" RUNAT="Server">
    function WriteHeader() {
    Response.Write("<H1>header</H1>");
    }
    </SCRIPT>
    <SCRIPT LANGUAGE ="VBScript" RUNAT="Server">
    sub WriteBody()
    Response.Write "<H1>body</H1>"
    end sub
    </SCRIPT>
    <SCRIPT LANGUAGE ="JScript" RUNAT="Server">
    function WriteFooter() {
    Response.Write("<H1>footer</H1>");
    }
    </SCRIPT>


    <SCRIPT LANGUAGE ="VBScript" RUNAT="Server">
    Sub main()
    Call WriteHeader()
    Call WriteBody()
    Call WriteFooter()
    end sub


    Call Main()
    </SCRIPT>

  • The fact that the JScript interpreter runs first has been published aspect of ASP since version 1.0. There is nothing particularly bad about this and is quite logical. Two languages - two interpreters, one of them simply has to execute first. Visual Studio's old Design Time Controls relied on this order of execution to create the objects that were manipulated in VBScript.
  • It might not be the best of ideas, but sometimes it's quite handy. If I recall correctly, JScript has much better support for UTC time parsing/formatting than VBScript (may have changed). I remember using a small preamble in Jscript that formatted a date/time in UTC, and then using that date further on my my 'real' code, in VBscript.
    But I agree it can be confusing, switching syntax in one page.
  • The death of WSCs has been greatly exaggerated, Rob. :)

    They don't mix well with .NET, but for direct use from traditional script, they work nicely. Or were you referring only to a webserver context?
  • There is no reason not to mix scripting languages in ASP. I have found it quite useful at times (ever try setting a cookie expiration with a JScript date?). It's important, of course, to encapsulate all cross-language segments in functions/Functions/Subs. This effectively eliminates the "order of execution" problem.

    http://msdn.microsoft.com/library/en-us/dnvid/html/msdn_vbnjscrpt.asp?frame=true#vbnjscrpt_working

  • Hehe;

    Ok, my 2.1 cents.

    I Use Jscript for both client and server site. An old school, not object oriented, coworker of mine uses VBscript.

    When I came to the team I found many of his work in use. I rewrote some and some I prefered keep as is due to retro-compatibility issues and lazyness.

    The way we can make it work is simple, lybraries. All your VB work must be procs and functions that you include in your pages and you call it from any part of your pages as func().

    Once your library is compiled the calls to the functions will work in the correct points where you put them.

    The only problem you can find is exchanging Arrays, avoid them. It can be done but needs conversion (you must write) and is CPU consumming.

    In response to Dave Anderson:
    Response.Cookies("myCookie").expires=expireDate.getVarDate();

    In the future forget VBS and JS, let's move to C#

    See ya, :)

    Rick.

  • I've come across a number of issues when using IHttpAsyncHandlers, When trying to using HttpAsyncHandlers with ThreadPools the HttpRequest.Files.Count always returns 0 regardless of the number of file posted by the form.
  • Why move to C#? What's so special about it?
  • We have been using mixed language scripting to good effect. What is possible:
    1. Create objects from JScript classes
    2. Call the methods onsce you do the appropriate set command in VBscript
    3. Call function/procedures from mixed libraries.

    It is convenient to think of server-side script classes and client-side script classes from the same code base. For example a set of client-side vaslidators which are also used at the server.

    Or, model panels at the server and the client wtih the same code base.
  • I just wanted to thank Ricardo Araujo for his solution on expiration date with JScript, before knowing it i've been writing manually the correct date format... horrible!

  • How does (w/c)script implement execution of WSFs then?

    For instance, the following code is legitimate, and executes in order of writing:

    <job>

    <script language="VBScript">

    MsgBox "Hello, VBScript World!"

    </script>

    <script language="JScript">

    WScript.Echo('Hello, JScript World!');

    </script>

    <script language="VBScript">

    MsgBox "Hello, VBScript World, Again!"

    </script>

    </job>

    The same is true for Function calls too:

    <job>

    <script language="VBScript">

    Sub Func1(i)

    If i = 1 Then

    Func2()

    Else

    MsgBox("At Last!")

    End If

    End Sub

    </script>

    <script language="JScript">

    function JFunc(k) {

    Func1(k)

    }

    </script>

    <script language="VBScript">

    Sub Func2()

    JFunc(2)

    End Sub

    JFunc(1)

    </script>

    </job>

    Why couldn't ASP act the same? Why can't it do it now?

  • > Why couldn't ASP act the same? Why can't it do it now?

    Because ASP and WSH (and Internet Explorer) have completely different compilation models.  When the first page request comes in for a page, ASP:

    * transforms the page into a series of script blocks

    * compiles each block into the appropriate engine

    * caches the compiled engine state

    * runs each engine, one after the other.

    When the second request comes in, ASP skips the first three steps and just does the last.

    ASP could do it the WSH/IE way, but it would have to recompile every page from scratch every time. That consumes time and memory, and ASP is designed for speed.

    With WSH/IE, there is no "second time". Every time a script runs is the first time, so there is no reason whatsoever to try to eke out more performance by caching compiled state and deferring execution until all the state is known. WSH/IE simply compiles and runs each block as it sees it, rather than doing all the compilation first, then all the running.

  • I don't using more script blocks prevents you from caching their compiled states. Let's say we have:

    <script language"VBScript" runat="server">

    WriteOut(sHeader)

    </script>

    <script language"JScript" runat="server">

    WriteOut(sContent)

    </script>

    <script language"VBScript" runat="server">

    WriteOut(sFooter)

    </script>

    Why can't we create THREE engines, one per script block, CACHE their compiled states, and run them SEQUENTIALLY? Of course, in this case, 20 script blocks would turn to 20 engines, but that's the ASP programmer's problem. Why shouldn't the infrastructure ALLOW him combining different languages?

  • It's always struck me as a little bit odd that Active Server Pages, a web server, encourages developers to use VBScript and JScript to write server-side scripts. I mean, the whole point of a web server is that it produces complex strings as blindingly

Page 1 of 1 (15 items)