HOWTO: Use Relative Links to Develop Web Applications on Windows Professional SKU and Publish as Websites on Server SKU

The following situation is commonly experienced by many consultants and web application developers that develop against IIS on a professional "SKU" of Windows while deploying against a server "SKU" of Windows.

Namely, since IIS on the professional editions of Windows, either Windows 2000 Professional or Windows XP Professional, only allow one website definition, how can one easily develop multiple web applications and still deploy them as multiple websites? The following is a recent illustrative question.

Question:

I have a significant issue regarding developing on XP for a Win2003 server.

* I have a development box running IIS 5.1 on Windows XP Pro.
* I have a production server running IIS 6.0 on Windows 2003.
* The development web is located in it's own application at https://localhost/WEB1/.
* The production web is located in it's own web at https://www.myweb1.com.

If I create an image folder in the root of the virtual directory WEB1, I can access the images directory within my default.aspx file in the two following manners:

https://localhost/WEB1/default.aspx

1. <img src="/WEB1/images/spacer.gif">
2. <img src="images/spacer.gif">

I want to build a user control under the "/WEB1/uc/" directory and it has images it references as well. The user control can references image in the following ways:

1. <img src="/WEB1/images/spacer.gif">
2. <img src="images/spacer.gif">

Assuming I use the control in aspx pages located at the root, the second relative directory method is fine, but if I use the same control in a file located in the folder at //localhost/WEB1/Admin/ then I cannot use relative references, I must use absolute references in the <img> tag example 1.

OK so what happens when I upload my web to the server???? All root-based references will now be broken, but I cannot use relative paths for images because the use of a control in different nodes of the folder tree will break the image src reference.

Is there a way in IIS 5.1 (windows XP) to convince the server that virtual web /WEB1/ is the root? I really want to use:

<img src="/images/spacer.gif">

so that I can transfer my web to my webserver without adjustment, use the user controls in different sub directories no matter how deep.

Any ideas?????

Answer:

Actually, the question is not related to IIS nor web server configuration.

The reason is because the absolutele/relative URL you give in an <IMG> or <A> tag inside of an HTML page is NOT processed by the web server. It is processed by the web BROWSER, which must interpret and figure out what URL to retrieve for display composition.

Thus, you are really asking "how do I get the browser to interpret a relative URL like "images/spacer.gif" to be https://localhost/WEB1/images/spacer.gif when served from one machine, and https://www.myweb1.com/images/spacer.gif from another?"

I am going to show one technique to use relative URLs which works on just about any server-side dynamic framework (like ASP or ASP.Net). It will allow your application to function as a virtual directory on XP Pro and still automatically work when you deploy it as a stand-alone website on the production server... without changing anything and perfectly using long-established public HTML standards.

The "BASE" HTML Element

What you describe is exactly the functionality defined by the HTML "BASE" element, defined here: https://www.w3.org/TR/REC-html40/struct/links.html#h-12.4

So, the resulting HTML produced by dynamic webpage on the server should look like:

  1. On your XP dev machine

     <BASE href="https://localhost/WEB1/">
    ...
    <IMG href="images/spacer.gif">
    
  2. On the production web server

     <BASE href="https://www.myweb1.com/">
    ...
    <IMG href="images/spacer.gif">
    

The following ASP/ASP.Net code shows how to accomplish this without needing to change anything for deployment (I trust you know how to setup your application for your personal "debug" modes and customer's "release" version). It is important to note that this approach works no matter what the URL looks like as long as you follow your own stated rules where /images stays relative to /default.aspx:

  1. If debug is true, then your URLs look like https://localhost/WEB1/default.aspx and https://localhost/WEB1/images/spacer.gif
  2. if debug is false, then your URLs look like https://www.myweb1.com/default.aspx and https://www.myweb1.com/images/spacer.gif

Enjoy.

//David

 <%
dim debug, BASE
debug = true

if debug then
    BASE = Request.ServerVariables( "SERVER_NAME" ) + _
           MID( Request.ServerVariables( "APPL_MD_PATH" ), _
                LEN( Request.ServerVariables( "INSTANCE_META_PATH" ) ) + 6 )
else
    BASE = Request.ServerVariables( "SERVER_NAME" )
end if
%>

<HTML>
    <HEAD>
    <TITLE>Test Page</TITLE>
    <BASE href="https://<%=BASE%>/">
    </HEAD>
    <BODY>
Picture: <IMG src="images/spacer.gif">
    </BODY>
</HTML>