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:
- Create HTA application
- Load binary (using image as an example) into HTA’s DOM (just like we do it with browser)
- Create
ADODB.Stream
and POST it with Msxml2.XMLHTTP
Step 1
Let’s create sample.hta file that looks like this:
Use any HTML producing software to create sample.html which has the following elements:
Rename HTML file to HTA. Create HEADER
like this:
<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:
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;
}
}
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:
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
.
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;
binData.Open();
binData.Type = 1;
binData.LoadFromFile(filename);
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.Open("POST",<a href="http://sample/scripts/intxml.dll/bimport?nm=">http:
"&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:
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:
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