Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

How to Stream Binaries and Text from the Client Machine to Server using HTA

4.67/5 (3 votes)
13 Sep 2005CPOL2 min read 1   1K  
Streaming binaries and text from the client machine to server using HTA

Introduction

Microsoft does not support use of ADODB.Stream within Internet Explorer since the release of Internet Explorer 5.01. It provides us with another powerful, yet easy solution to utilize the power of JavaScript and browser's objects. HTA application packs the power of Internet Explorer with its HTML-like technology.

Summary

The following example can be summarized in the following steps:

  1. Create HTA application
  2. Load binary (using image as an example) into HTA’s DOM (just like we do it with browser)
  3. Create ADODB.Stream and POST it with Msxml2.XMLHTTP

Step 1

Let’s create sample.hta file that looks like this:

Image 1

Use any HTML producing software to create sample.html which has the following elements:

  • Three buttons:
    • Save - to upload binary source to Web server
    • Preview – to load empty image with what you select from file browser.
    • Cancel – to close window
  • File browser

    HTML
    <INPUT size="20" name="imagebrowser" type='file'> 
  • Empty image at the bottom

    HTML
    <IMG src="blank.jpg" border="0">

Rename HTML file to HTA. Create HEADER like this:

HTML
<HTA:APPLICATION id="345" BORDERSTYLE="thin" MINIMIZEBUTTON="yes" 
    MAXIMIZEBUTTON="yes" SELECTION="no" INNERBORDER="yes" SCROLLFLAT="yes" 
    SCROLL="yes" WINDOWSTATE="normal" SYSMENU="yes" SINGLEINSTANCE="yes" 
    SHOWINTASKBAR="yes" ICON="20.ico" CAPTION="yes" BORDER="thick" 
    APPLICATIONNAME="sample"> 

Take note of all the useful properties which help you to control HTA appearance and functionality, just like you would control any custom client application.

Click this link for useful information.

Step 2

Preview image; choose file from your drive and press the Preview button. The following JavaScript gets executed:

JavaScript
function DoPreview() { 
var filename = document.forms[0].imagebrowser.value; 
var Img = new Image(); 
if (navigator.appName == "Netscape") { 
alert("Previews do not work in Netscape."); 
}else{ 
Img.src = filename; 
document.images[3].src = Img.src; 
document.images[3].name = filename; 
} 
} 

Image 2

Step 3

Now we are finally getting to the final part of our journey.

The reason why we use FileSystemObject is to provide the server with some extra information:

  • File name
  • File type

Create stream, set its type to binary and load it from file.

In the last step, we invoke Web developer’s best friend and prodigy - Msxml2.XMLHTTP.

JavaScript
function btn_send() { 
var fspec,fs, av,ts,bv, ForReading, ForWriting, TristateUseDefault; 
ForReading = 1; 
ForWriting = 2; 
TristateUseDefault = -2,
fs = new ActiveXObject("Scripting.FileSystemObject"); 
var filename = document.images[3].name; 
av = fs.OpenTextFile(filename, ForReading, false); 
fspec = fs.GetFile(filename); 
av.Close(); 
var binData = new ActiveXObject("ADODB.Stream"); 
binData.Mode = 3; //read write 
binData.Open(); 
binData.Type = 1; //adTypeBinary 
binData.LoadFromFile(filename); 
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 
xmlhttp.Open("POST",<a href="http://sample/scripts/intxml.dll/bimport?nm=">http://sample/scripts/intxml.dll/bimport?nm=</a>+fspec.ShortName+
    "&type="+fspec.type,false); 
xmlhttp.send(binData.Read(-1)); 
binData.Close(); 
} 

Click this link for useful information.

In some cases, you might find it useful to invoke MSXML2.DOMDocument component and make your binary - part of XML or SOAP request. Also if security is an issue, encryption might make sense. To illustrate this point, something like this can be done:

JavaScript
binData = encode64(data); 
xmlImage(binData,fspec.ShortName,fspec.size,fspec.type); 

These lines should be plugged in right before xmlhttp.send(binData.Read(-1));

If you decide to go this rocky road, there are a couple more functions for you:

JavaScript
function encode64(input) {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
var output = ""; 
var chr1, chr2, chr3; 
var enc1, enc2, enc3, enc4; 
var i = 0; 
do { 
chr1 = input.charCodeAt(i++); 
chr2 = input.charCodeAt(i++); 
chr3 = input.charCodeAt(i++); 
enc1 = chr1 >> 2; 
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 
enc4 = chr3 & 63; 
if (isNaN(chr2)) { 
enc3 = enc4 = 64; 
} else if (isNaN(chr3)) { 
enc4 = 64; 
} 
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + 
keyStr.charAt(enc3) + keyStr.charAt(enc4); 
} while (i < input.length); 
return output; 
} 
function xmlImage(binData,ShortName,sz,tp){ 
var xml_dom = new ActiveXObject("MSXML2.DOMDocument"); 
xml_dom.loadXML('<?xml version="1.0" ?> <root/>'); 
var l_node1 = xml_dom.createElement("image"); 
var attr = xml_dom.createAttribute("name"); 
attr.value = document.forms[0].newname.value; 
l_node1.setAttributeNode(attr); 
attr = null; 
var attr = xml_dom.createAttribute("shortname"); 
attr.value = ShortName; 
l_node1.setAttributeNode(attr); 
attr = null; 
var attr = xml_dom.createAttribute("size"); 
attr.value = sz; 
l_node1.setAttributeNode(attr); 
attr = null; 
var attr = xml_dom.createAttribute("type"); 
attr.value = tp; 
l_node1.setAttributeNode(attr); 
attr = null; 
l_node1.dataType = "bin.base64"; 
l_node1.nodeTypedValue = escape(im); 
xml_dom.documentElement.appendChild(l_node1); 
Return xml_dom; 
} 

Limitations and Recommendations

  • Maximum size of file you can upload is less than 50 KB

History

  • 13th September, 2005: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)