ASP: Mixed Include Techniques |
Written March 3rd, 2008.
|
Classic ASP provides two ways for linking to other code files: the pound-include comment (
The biggest difference between these two methods of code inclusion is the first imports a new Active Serve Page and the second imports functions (or classes) written in a specific Active Script language. Additionally the logic in a script tag is always run after everything in straight-up ASP files. This has two side effects:
The global
Okay I said I wasn't going to talk about VBScript, but here's a doozey of an issue to keep in mind. External JScript files are executed before your ASP code if the language is set to VBScript. It must have something to do with the way ASP handles language switching, but I couldn't tell you for certain.
<--#include file="filename.asp" -->
) and a server-side script tag (<--script runat="server" src="filename.js" language="JScript"></script>
). In general I prefer to use the latter, because I can write portable ECMAScript and worry less about the syntax highlighting issues that come with combining languages (HTML/JScript/VBScript) in the same file. I'd like to point out here at the beginning that ASP by itself is a platform and not a language, it actually stands for "Active Server Page(s)". Being a JavaScript buff myself, I tend to use Microsoft's implementation of that language which is technically labeled JScript. Still when people ask if you write ASP code generally they mean VBScript, which is a fine language but not one I'm overly familiar with or will be using here -- sorry.The biggest difference between these two methods of code inclusion is the first imports a new Active Serve Page and the second imports functions (or classes) written in a specific Active Script language. Additionally the logic in a script tag is always run after everything in straight-up ASP files. This has two side effects:
- Global variables declared in an external script file are not available to the code in an ASP.
- Global code in an external script is run after everything in the ASP file (unless
Response.End()
is used) and can therefore cause exceptions which screw something up which already succeeded.
Response.End()
with the ASP to ensure other weird global code won't execute and cause problems. In order to have your scripts play nice, you'll also have to avoid relying on global variables because they simply won't be initialized, though it is possible to set global variables in an external script through a function that is called from within the ASP.The global
this
context reference is different when it is created from code in the ASP versus when external script code is run. I can't explain exactly how, but basically you can't enumerate it like a normal JavaScript object because it simply isn't. Thus the following would cause an exception ...test.asp
<%@Language=JScript%>
<script language="JScript" src="module.js" runat="server"></script>
Test();
While you can't enumerate themodule.js
function Test()
{
for (var nm in this)
{
// ...
}
}
this
object, you can still access it for direct reads or explicit assignments. Whatever you assign to this
will from then-on be a globally accessible variable in both the ASP code and external scripts.Okay I said I wasn't going to talk about VBScript, but here's a doozey of an issue to keep in mind. External JScript files are executed before your ASP code if the language is set to VBScript. It must have something to do with the way ASP handles language switching, but I couldn't tell you for certain.
ASP: VBScript to JavaScript |
Written circa 2000.
|
This was a conversation I had with a friend via instant messaging that I thought others might find useful. It's about his transition from using VBScript in ASP (Active Server Pages) to JavaScript (or rather, Microsoft's version which is JScript).
Him:this isnt working...
<%@ LANGUAGE="JScript" %>
<% option explicit %>
<% var test='test!'; %>
<% response.write test %>
am i retarded?
Him:its ok to say yes
Me:Yes, there is no such thing as "option explicit" in JavaScript
Me:Also, you need parenthesis around parameters. Also, I wouldn't put those in separate blocks, just use one ....
Me:<%@Language=JScript%><%
var test = "test!";
Response.Write(test);
%>
Him:thank you!
Him:OMG, the chains or opression have been cast aside!
Him:what about
set obj = server.createobject("object") ?
Me:var obj = Server.CreateObject("object");
Me:There is no SET
Me:Remember it's JavaScript, same function calls can be made (for the most part), but the language syntax is definitely different
Him:right, i wasnt sure about set and thats not the kind of thing i can search a pdf for
Him:what about "nothing" professor is that still a valid way to release an asp object?
Me:Nothing is a VB keyword, not a JS keyword
Him:im trying to find examples but everyone just says you can use js but noone actually showing any examples
Me:I know, maybe I should start writing some
Me:var obj = Server.CreateObject("blahblah");
obj = null;
Him:sweet
Him:and single quotes are safe?
Me:JS makes no distinction between single or double as long as you close with the same type you opened with...
'okay'
"okay"
'not okay"
"not okay'
Me:It's useful when you know what kind of quotes might be IN your string, because you can embed them easier ...
'some "double" quotes'
"some 'single' quotes"
Him:i like the first
Me:I noticed a lot of web pages use single quotes in JS, almost as if they don't realize you can use double quotes.
Him:coming from a vbs bg its crippled my thinking.. its like not a real string unless its in the ""... i mean.. you never know maybe it isnt a string.. maybe its some string out of access that will never evaluate..
Him:like why is this an unterminated string constant?
objFileSys = objFSO.getFile(envSys+"\"+f);
Me:Backslashes are used to escape characters. Remember how I told you \r\n is CRLF? So "line1\r\nline2". So if JS sees a backslash, it sees an escape character. In your case a backslash followed by a quote ( \" ) means simply a quote character. This allows you to put quotes inside quotes:
"outside \"inside quotes\" outside"
Him:oh yeah
Him:so i need an /\
Me:Then to put an actual backslash CHARACTER into a string, you need to escape it as well. Do that by using TWO backslashes:
"c:\\windows"
Him:cool
Me:If you ever learn C/C++/Java/C#/PHP, they have the same escaping system.
Him:is there a way you can define a var that can contain multi level values like
var.value1 = "1"
var.value2 = "2" ?
Me:I don't understand what you're asking, show me what you'd do in VBS.
Him:i dont know what im talking about honsetly i just know in lua i can make a var like this
test.letter1 = "A"
test.letter2 = "B"
test.letter3 = "C"
and then use the value like test=test.letter1
Him:i was wondering if there was anything like that
Me:So you mean a variable is constrained to a specific set of values (e.g. an enumeration)? No, that is not supported
Him:not really usefule i was just wondering
Me:You would either just use the value you wanted (test = "C") or create a variable holding the value(s) you wanted (test = test_letter1)
Him:what about a hash or dictionary equiv, you know a tutorial for that?
Him:wait, i think i found one
Me:Hash/dictionary/associative arrays are native to JavaScript. An object you create can be used or accessed like one.
Me:An example will help here though ...
var dic = new Object;
dic["apple"] = "A sweet fruit or an over-hyped company";
dic["pear"] = "A sweet fruit or how you look with shorts on";
var key = "apple";
Response.Write(dic[key]);
Me:You could even access these directly:
Response.Write(dic.apple);
Response.Write(dic.pear);
Me:To enumerate an object (or lo, a dictionary as it would've been known to you):
for (key in dic)
{
Response.Write(key + ": " + dic[key]);
}
Him:so what your telling me is the only thing thats useful in vbs, the dictionary is functionality found in any js object?
Me:Yes, it's one of its strengths. It makes it so you can do all kinds of crazy, dynamic shit
Him:godamnit, why the fuck is vbs even sugested
Me:People are familiar with it, and it's not as scary looking with all the braces and semi-colons
Him:yeah.. the braces are intimidating at first, i dont know why but they serve to confuse
Me:Python and Ruby are a lot like JS without the braces (or one might say, it's the other way around).
Me:The one dominating reason why I use JS over those other two is 1. you can use it right-away on ANY fresh Windows install (due to WSH), and 2. EVERYONE's browser supports JS these days
Him:now why is it then when i call server.mappath it tells me that 'server' is not defined.. oh does it have to be 'Server'?
Him:ha
Me:Yes, and case sensitivity is a big weak point (in my opinion)
Me:But, it's too late to change it now. Too many scripts might explode into fiery kiddie bits if we make the language insensitive to case
Him:you dont like being able to have a VAR thats one thing and var thats another?
Me:I do only when it serves to irritate people who will inherit my code
Him:hahahaha
Him:good point
Him:couldnt you do some kind of lcase execute call thing to ensure everything was allways lowercase
Me:Hmm, I'm not sure what you mean. A lot of objects have a specific case, like "Server" the 'S' has to be upper-case
Him:well thats why i click the mouse for a living rather then press the keys
Him:hmmm i cant replace on a server var.. do i have to convert it to a string youd think it would already be one..
Me:Ok, so you mean Request.QueryString() or something like that? What are you trying to do now? You can show me VBS and I'll help you write the JS
Him:var = Request.ServerVariables("APPL_PHYSICAL_PATH").replace(/chars/, "newcars");
Him:Object doesn't support this property or method
Me:This is one of those things that is fortunately hidden from you in VB, because the ASP objects were tailored for that language. In JavaScript you can do one of two things:
var s = Request.ServerVariables("name").Item(1).replace(....);
or
var s = (""+Request.ServerVariables("name")).replace(....);
Him:oh i get you, is there a parseString function or is that wrong too
Me:What do you want to parse a string to? An int?
var i = parseInt("54");
Me:if (isNaN ( i ) )
{
// parsing failed
}
Me:NaN == Not a Number
Him:and how do you make a replace global?
Him:/g?
Me:Ah, another annoyance, yes. You need to use a regular expresion, correct
Me:var s = "hello world world".replace(/world/g, "planet");
Him:ok i got it, i shouldnt have asked that when i could have googled it so easy
(end)
Him:this isnt working...
<%@ LANGUAGE="JScript" %>
<% option explicit %>
<% var test='test!'; %>
<% response.write test %>
am i retarded?
Him:its ok to say yes
Me:Yes, there is no such thing as "option explicit" in JavaScript
Me:Also, you need parenthesis around parameters. Also, I wouldn't put those in separate blocks, just use one ....
Me:<%@Language=JScript%><%
var test = "test!";
Response.Write(test);
%>
Him:thank you!
Him:OMG, the chains or opression have been cast aside!
Him:what about
set obj = server.createobject("object") ?
Me:var obj = Server.CreateObject("object");
Me:There is no SET
Me:Remember it's JavaScript, same function calls can be made (for the most part), but the language syntax is definitely different
Him:right, i wasnt sure about set and thats not the kind of thing i can search a pdf for
Him:what about "nothing" professor is that still a valid way to release an asp object?
Me:Nothing is a VB keyword, not a JS keyword
Him:im trying to find examples but everyone just says you can use js but noone actually showing any examples
Me:I know, maybe I should start writing some
Me:var obj = Server.CreateObject("blahblah");
obj = null;
Him:sweet
Him:and single quotes are safe?
Me:JS makes no distinction between single or double as long as you close with the same type you opened with...
'okay'
"okay"
'not okay"
"not okay'
Me:It's useful when you know what kind of quotes might be IN your string, because you can embed them easier ...
'some "double" quotes'
"some 'single' quotes"
Him:i like the first
Me:I noticed a lot of web pages use single quotes in JS, almost as if they don't realize you can use double quotes.
Him:coming from a vbs bg its crippled my thinking.. its like not a real string unless its in the ""... i mean.. you never know maybe it isnt a string.. maybe its some string out of access that will never evaluate..
Him:like why is this an unterminated string constant?
objFileSys = objFSO.getFile(envSys+"\"+f);
Me:Backslashes are used to escape characters. Remember how I told you \r\n is CRLF? So "line1\r\nline2". So if JS sees a backslash, it sees an escape character. In your case a backslash followed by a quote ( \" ) means simply a quote character. This allows you to put quotes inside quotes:
"outside \"inside quotes\" outside"
Him:oh yeah
Him:so i need an /\
Me:Then to put an actual backslash CHARACTER into a string, you need to escape it as well. Do that by using TWO backslashes:
"c:\\windows"
Him:cool
Me:If you ever learn C/C++/Java/C#/PHP, they have the same escaping system.
Him:is there a way you can define a var that can contain multi level values like
var.value1 = "1"
var.value2 = "2" ?
Me:I don't understand what you're asking, show me what you'd do in VBS.
Him:i dont know what im talking about honsetly i just know in lua i can make a var like this
test.letter1 = "A"
test.letter2 = "B"
test.letter3 = "C"
and then use the value like test=test.letter1
Him:i was wondering if there was anything like that
Me:So you mean a variable is constrained to a specific set of values (e.g. an enumeration)? No, that is not supported
Him:not really usefule i was just wondering
Me:You would either just use the value you wanted (test = "C") or create a variable holding the value(s) you wanted (test = test_letter1)
Him:what about a hash or dictionary equiv, you know a tutorial for that?
Him:wait, i think i found one
Me:Hash/dictionary/associative arrays are native to JavaScript. An object you create can be used or accessed like one.
Me:An example will help here though ...
var dic = new Object;
dic["apple"] = "A sweet fruit or an over-hyped company";
dic["pear"] = "A sweet fruit or how you look with shorts on";
var key = "apple";
Response.Write(dic[key]);
Me:You could even access these directly:
Response.Write(dic.apple);
Response.Write(dic.pear);
Me:To enumerate an object (or lo, a dictionary as it would've been known to you):
for (key in dic)
{
Response.Write(key + ": " + dic[key]);
}
Him:so what your telling me is the only thing thats useful in vbs, the dictionary is functionality found in any js object?
Me:Yes, it's one of its strengths. It makes it so you can do all kinds of crazy, dynamic shit
Him:godamnit, why the fuck is vbs even sugested
Me:People are familiar with it, and it's not as scary looking with all the braces and semi-colons
Him:yeah.. the braces are intimidating at first, i dont know why but they serve to confuse
Me:Python and Ruby are a lot like JS without the braces (or one might say, it's the other way around).
Me:The one dominating reason why I use JS over those other two is 1. you can use it right-away on ANY fresh Windows install (due to WSH), and 2. EVERYONE's browser supports JS these days
Him:now why is it then when i call server.mappath it tells me that 'server' is not defined.. oh does it have to be 'Server'?
Him:ha
Me:Yes, and case sensitivity is a big weak point (in my opinion)
Me:But, it's too late to change it now. Too many scripts might explode into fiery kiddie bits if we make the language insensitive to case
Him:you dont like being able to have a VAR thats one thing and var thats another?
Me:I do only when it serves to irritate people who will inherit my code
Him:hahahaha
Him:good point
Him:couldnt you do some kind of lcase execute call thing to ensure everything was allways lowercase
Me:Hmm, I'm not sure what you mean. A lot of objects have a specific case, like "Server" the 'S' has to be upper-case
Him:well thats why i click the mouse for a living rather then press the keys
Him:hmmm i cant replace on a server var.. do i have to convert it to a string youd think it would already be one..
Me:Ok, so you mean Request.QueryString() or something like that? What are you trying to do now? You can show me VBS and I'll help you write the JS
Him:var = Request.ServerVariables("APPL_PHYSICAL_PATH").replace(/chars/, "newcars");
Him:Object doesn't support this property or method
Me:This is one of those things that is fortunately hidden from you in VB, because the ASP objects were tailored for that language. In JavaScript you can do one of two things:
var s = Request.ServerVariables("name").Item(1).replace(....);
or
var s = (""+Request.ServerVariables("name")).replace(....);
Him:oh i get you, is there a parseString function or is that wrong too
Me:What do you want to parse a string to? An int?
var i = parseInt("54");
Me:if (isNaN ( i ) )
{
// parsing failed
}
Me:NaN == Not a Number
Him:and how do you make a replace global?
Him:/g?
Me:Ah, another annoyance, yes. You need to use a regular expresion, correct
Me:var s = "hello world world".replace(/world/g, "planet");
Him:ok i got it, i shouldnt have asked that when i could have googled it so easy
(end)