分享
 
 
 

(By Marco Nanni)Using XML to Improve File-Upload Processing

王朝other·作者佚名  2006-04-07
窄屏简体版  字體: |||超大  

原文地址:http://www.15seconds.com/issue/010522.htm

Summary

This article examines an example of multiple binary file upload for Web applications using Extensible Markup Language (XML) technology, without the typical limitation of traditional file upload processing. It describes how to use Microsoft XML Parser 3.0 (MSXML) and ActiveX Data Objects (ADO) Stream objects for a new upload strategy with several benefits. For example, no custom ASP components are required.

Introduction

To obtain a file upload with a traditional HTML page, on the client side we can use a form structured in the following way:

<FORM NAME="myForm"

ACTION="TargetURL.asp"

ENCTYPE="multipart/form-data"

METHOD="post">

<INPUT TYPE="file" NAME="myFile">

<INPUT TYPE="submit" VALUE="Upload File">

</FORM>

This solution presents several limitations both on the client and server side. We must use the POST method (because the GET can't manage this type of data), and we have no solutions to trigger a POST processing without using an HTML form. When we send data to the TargetURL, the browser loads this page as the new current page and we have an undesirable "context switch."

The ENCTYPE property defines the Multipurpose Internet Mail Extensions (MIME) encoding for the form and must be set to "multipart/form-data" for file upload forms. When we set this property to "multipart/form-data" we obtain a different structure of the POST buffer (which is also more complex) and the Request ASP object can't access the form contents. Therefore, we can read the POST buffer using the Request.binaryRead method, but we can't use scripting languages to do this. The Request.binaryRead method returns a VTarray (which is a variant array of unsigned one byte characters) while scripting languages can manage only variant variables. We can resolve this problem only by using a specific, custom ASP component or ISAPI extension, such as CPSHOST.DLL. This behavior is by design.

A New Upload Strategy

The idea underlying this article is the use of the following step: On the client-side:

create a XML document using the MSXML 3.0 object;

create a XML node with binary content;

populate this node with the content of the uploading file using the ADO Stream object;

send the document to the Web server using the XMLHTTP object.

On the server-side:

read the XML document from the Request ASP object;

read the content of the binary node and store it into a file on the server. Optionally, we can store it into a BLOB field of a database tables.

Before explaining the source code sample, we can make a few considerations about the solution used in this article.

XML Consideration

XML support many data types, such as numeric, float, character, etc. Many authors define XML as the ASCII of the future, but we can't forget that this technology can also describe binary information using the "bin.base64" data type. This feature is fully available with MS XML 3.0 Parser and to date requires a custom setup. This object provides some properties that enable a complete management of binary contents:

obj_node.dataType - This read/write property specifies the data type of the selected node. The XML parser supports more dataType values (see the MSDN reference for a complete list -- http://msdn.microsoft.com/library/psdk/xmlsdk/xmls3z1v.htm).

For binary contents we can use the "bin.base64" data type;

obj_node.nodeTypedValue - This read/write property contains the selected node's value expressed in its defined data type.

We can create an XML document with more "bin.base64"-type nodes that contain the files we want to upload. This consideration allows the processing of multiple uploading files with a single POST.

We can use the XMLHttpRequest object to send an XML document to a Web server using the POST method. This object provides client-side protocol support for communication with HTTP servers and allows us to send and receive MS XML Document Object Model (DOM) objects from a Web server. XMLHttpRequest is a built-in COM object with Internet Explorer 5 (not requiring a custom setup) and does not generate a context switch after posting data.

The ADO Stream Object

The previous considerations allow the creation (on the client-side) of an XML document with one or more binary nodes. Now we need to populate this node with the contents of the uploading files. Unfortunately, scripting languages can't access the local file system, and the Scripting.FileSystemObject (which is a built-in COM object of the recent Win32 platform) to date can't manage binary files. This behavior is by design. We need an other COM object that provides the access to the local binary files.

The ADO Stream object (which is a COM object included in the MDAC 2.5 components) provides the means to read, write, and manage a stream of bytes. This byte stream may be text or binary and hasn't particular size limitations. In ADO 2.5, Microsoft has introduced the Stream object without any dependency in the ADO object model hierarchy; therefore, we can use the Stream object without binding it to the other ADO objects.

In this article, we use the Stream object to access file content and store it into XML node, and vice versa.

Client-Side Code

The following code sample provides a client-side file upload using Stream and MSXML objects:

<HTML>

<HEAD><TITLE>File Send</TITLE></HEAD>

<BODY>

<INPUT id=btn_send name="btn_send" type=button value="FILE SEND">

<DIV id=div_message>Ready</DIV>

</BODY>

</HTML>

<SCRIPT LANGUAGE=JavaScript>

// files upload function

function btn_send.onclick()

{

// create ADO-stream Object

var ado_stream = new ActiveXObject("ADODB.Stream");

// create XML document with default header and primary node

var xml_dom = new ActiveXObject("MSXML2.DOMDocument");

xml_dom.loadXML('<?xml version="1.0" ?> <root/>');

// specify namespaces datatypes

xml_dom.documentElement.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes");

// create a new node and set binary content

var l_node1 = xml_dom.createElement("file1");

l_node1.dataType = "bin.base64";

// open stream object and read source file

ado_stream.Type = 1; // 1=adTypeBinary

ado_stream.Open();

ado_stream.LoadFromFile("c:\\tmp\\myfile.doc");

// store file content into XML node

l_node1.nodeTypedValue = ado_stream.Read(-1); // -1=adReadAll

ado_stream.Close();

xml_dom.documentElement.appendChild(l_node1);

// we can create more XML nodes for multiple file upload

// send XML documento to Web server

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

xmlhttp.open("POST","./file_recieve.asp",false);

xmlhttp.send(xml_dom);

// show server message in message-area

div_message.innerHTML = xmlhttp.ResponseText;

}

</SCRIPT>

Server-Side Code

The following code sample provides a server-side file upload using the same objects:

<%@ LANGUAGE=VBScript%>

<% Option Explicit

Response.Expires = 0

' define variables and COM objects

dim ado_stream

dim xml_dom

dim xml_file1

' create Stream Object

set ado_stream = Server.CreateObject("ADODB.Stream")

' create XMLDOM object and load it from request ASP object

set xml_dom = Server.CreateObject("MSXML2.DOMDocument")

xml_dom.load(request)

' retrieve XML node with binary content

set xml_file1 = xml_dom.selectSingleNode("root/file1")

' open stream object and store XML node content into it

ado_stream.Type = 1 ' 1=adTypeBinary

ado_stream.open

ado_stream.Write xml_file1.nodeTypedValue

' save uploaded file

ado_stream.SaveToFile "c:\tmp\upload1.doc",2 ' 2=adSaveCreateOverWrite

ado_stream.close

' destroy COM object

set ado_stream = Nothing

set xml_dom = Nothing

' write message to browser

Response.Write "Upload successful!"

%>

We can also use the ADO Stream to store the uploading file into a BLOB field of a database table. (See the related link for more information.)

Benefits

This strategy allows a file upload processing with several benefits:

It does not trigger a context switch on the client.

No custom ASP components are required.

We can use this strategy for multiple binary file upload in a single POST process.

This process is totally implemented into a SCRIPT code. We can easily insert this code into a script library since no HTML objects are required. We can also implement this algorithm (on the client-side) using any other language that supports the COM interface, such as Visual Basic (VB), Delphi, PowerBuilder, etc.

Security and System Consideration

We can use this solution only for an intranet application because it requires an IE5 security setting with low protection. We must:

enable script and activeX controls. This parameter allows the execution of the "myobj = new activexobject(...)" JScript statement;

enable access to data source through domain. This parameter allows the use of the Stream object on the client side. We must also install MS XML DOM 3.0 and MDAC 2.5 both on the client and server side.

References

Read Tiago Halm's article about traditional file-upload processing at http://www.15seconds.com/Issue/001003.htm

For a description of the data types supported by MS XML parser, see http://msdn.microsoft.com/library/psdk/xmlsdk/xmls1cbp.htm and http://msdn.microsoft.com/library/psdk/xmlsdk/xmls3z1v.htm

A sample of creating an XML document with binary data in VB is available at http://support.microsoft.com/support/kb/articles/Q254/3/88.ASP

For a Microsoft reference on the ADO Stream object, see http://msdn.microsoft.com/library/psdk/dasdk/mdao1ajx.htm .

Another sample for managing BLOB and binary files can be found at http://support.microsoft.com/support/kb/articles/Q258/0/38.ASP.

About the Author

Marco Nanni is an Italian Web developer with experience in (D)HTML and XML technology used for implementing enterprise solutions. Marco can be contacted at: mnanni@lycos.it.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有