개요
이 기사에서는 XML 기술을 사용하여 파일을 업로드하는 예를 설명합니다. 이 방법에는 기존 방법의 제한 사항이 없습니다. 이 예에서는 MSXML3.0 및 ADO 스트림 개체를 사용하여 이 새로운 업로드 방법을 구현하는 방법을 설명합니다. 전용 업로드 구성 요소가 필요하지 않은 등 많은 이점이 있습니다.
소개
HTML 웹 페이지에서 업로드 기능을 얻으려면 클라이언트에서 다음 형식의 FORM을 사용할 수 있습니다.
<FORM NAME="myForm"
ACTION="대상URL.asp"
ENCTYPE="다중 부분/양식-데이터"
방법="게시">
<입력 유형="파일" 이름="내파일">
<INPUT TYPE="제출" VALUE="파일 업로드">
</FORM>
이 솔루션에는 클라이언트와 서버를 모두 사용하는 데 많은 제한이 있습니다. 먼저, GET 방식으로는 이러한 폼 데이터를 처리할 수 없기 때문에 POST 방식을 사용해야 합니다. 또한 양식을 사용하지 않고 POST 작업을 트리거할 방법이 없습니다. 데이터를 양식 핸들러로 보낸 후 브라우저는 핸들러를 새 페이지로 로드하고 사용자는 불쾌한 페이지 전환을 보게 됩니다.
ENCTYPE 속성은 양식에 대한 MIME 인코딩 방법을 정의합니다. 파일 업로드를 위한 양식의 ENCTYPE 속성은 "multipart/form-data"를 사용해야 합니다. 이 속성을 "multipart/form-data"로 설정하면 ASP의 요청 개체가 이러한 양식 콘텐츠에 액세스할 수 없는 POST 버퍼(복합 구조)가 생성됩니다. 따라서 Request.binaryRead 메서드를 사용하여 이 데이터에 액세스할 수 있지만 스크립팅 언어를 사용하여 액세스할 수는 없습니다. Request.binaryRead 메소드는 VTaray 유형 데이터(부호 없는 1바이트 문자만 포함하는 Variant 유형 배열)를 반환합니다. 하지만 스크립팅 언어는 Variant 데이터만 처리할 수 있습니다. 이 문제를 해결하려면 전용 ASP 업로드 구성 요소나 CPSHOST.DLL과 같은 ISAPI 확장만 사용할 수 있습니다. 이는 디자인의 한계입니다.
새로운 업로드 계획은
다음 단계를 따라야 합니다.
클라이언트:
MSXML 3.0을 사용하여 바이너리 콘텐츠에 대한 XML 노드를 생성합니다. 업로드된 파일 데이터를 노드에 넣기 위해 XMLHTTP 개체를 웹 서버에 보냅니다
. 옆:
Request 객체에서 XML 문서를 읽고, 바이너리 노드의 데이터를 읽고, 이를 서버의 파일에 저장합니다. 물론 데이터베이스의 BLOB 필드에 저장할 수도 있습니다.
이 코드를 설명하기 전에 이 솔루션에 대해 생각해 볼 수 있습니다.
XML에 대한 생각
XML 형식은 숫자, 부동 소수점, 문자 등과 같은 다양한 데이터 유형을 지원합니다. 많은 작성자가 XML을 ASCII 형식으로 정의하지만 XML 기술이 이진 정보를 설명하기 위해 "bin.base64" 데이터 유형을 사용할 수도 있다는 사실을 무시할 수 없습니다. 이 기능은 MS XML3.0 파서에서 완전히 지원되지만 현재는 몇 가지 특별한 설정이 필요합니다. 이 객체는 바이너리 데이터를 완전히 제어할 수 있는 몇 가지 속성을 제공합니다.
obj_node.dataType - 이 읽기-쓰기 속성은 특정 노드의 데이터 유형을 정의합니다. MSXML 파서는 더 많은 데이터 유형을 지원합니다(MSDN: http://msdn.microsoft.com/library/psdk/xmlsdk/xmls3z1v.htm 참조).
바이너리 데이터의 경우 "bin.base64" 유형을 사용할 수 있습니다.
obj_node.nodeTypedValue - 이 읽기-쓰기 속성에는 지정된 유형의 측면에서 지정된 노드를 나타내는 데이터가 포함됩니다.
업로드된 파일이 포함된 여러 bin.base64 유형 노드를 포함하는 XML 문서를 생성할 수 있습니다. 이 기능을 사용하면 하나의 POST를 사용하여 여러 파일을 한 번에 업로드할 수 있습니다.
XMLHttpRequest 개체와 POST 메서드를 사용하여 XML 문서를 웹 서버에 보낼 수 있습니다. 이 개체는 HTTP 서버에 클라이언트 측 프로토콜 지원을 제공하여 MS XMLDOM 개체를 웹 서버에서 보내고 받을 수 있도록 합니다. XMLHttpRequest는 Internet Explorer 5에 내장된 COM 개체이며(사용자 정의 설치가 필요하지 않음) 전송 후 페이지를 변환할 필요가 없습니다.
ADO 스트림 개체에 대해 생각하기
클라이언트 측에서 하나 이상의 바이너리 노드를 포함하는 XML 문서를 만들 수 있습니다. 또한 노드를 파일 콘텐츠로 채워야 합니다. 불행하게도 스크립팅 언어는 로컬 파일 시스템에 접근할 수 없으며, Scripting.FileSystem 개체(Win32 시스템의 내장 개체)는 지금까지 바이너리 파일에 접근할 수 없었습니다. 이는 디자인의 한계입니다. 따라서 로컬 바이너리에 대한 액세스를 제공할 수 있는 다른 COM 개체를 찾아야 합니다.
ADO 스트림 개체(MDAC 2.5의 구성 요소)는 이진 스트림 데이터를 읽고, 쓰고, 관리하는 방법을 제공합니다. 바이트 스트림의 내용은 텍스트 또는 바이너리 데이터일 수 있으며 용량 제한이 없습니다. ADO 2.5에서 Microsoft가 도입한 Stream 개체는 ADO 개체 구조의 어떤 계층에도 속하지 않으므로 번들링 없이 개체를 사용할 수 있습니다.
이 문서에서는 Stream 개체를 사용하여 파일 콘텐츠에 액세스한 다음 해당 콘텐츠를 XML 노드에 저장합니다.
클라이언트 측의
Stream 및 MSXML 개체를 사용하여 파일 업로드 작업을 완료합니다.
<HTML>
<HEAD><TITLE>파일 보내기</TITLE></HEAD>
<본문>
<INPUT id=btn_send name="btn_send" 유형=버튼 값="FILE SEND">
<DIV id=div_message>준비</DIV>
</BODY>
</HTML>
<SCRIPT LANGUAGE=javascript>
// 업로드 기능
함수 btn_send.onclick()
{
//ADO 스트림 객체 생성
var ado_stream = new ActiveXObject("ADODB.Stream")
// 기본 헤더 정보와 루트 노드를 포함하는 XML 문서를 생성합니다.
var xml_dom = new ActiveXObject("MSXML2.DOMDocument");
xml_dom.loadXML('<?xml version="1.0" ?> <root/>');
//데이터 유형 지정
xml_dom.documentElement.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes");
// 새 노드를 생성하고 이진 데이터 노드로 설정합니다.
var l_node1 = xml_dom.createElement("file1");
l_node1.dataType = "bin.base64";
//Stream 객체를 열고 소스 파일을 읽습니다.
ado_stream.Type = 1; // 1=adTypeBinary
ado_stream.Open();
ado_stream.LoadFromFile("c:\tmp\myfile.doc");
//파일 내용을 XML 노드에 저장
l_node1.nodeTypedValue = ado_stream.Read(-1) // -1=adReadAll;
ado_stream.Close();
xml_dom.documentElement.appendChild(l_node1);
// 여러 바이너리 노드를 생성하고 한 번에 여러 파일을 업로드할 수 있습니다.
// XML 문서를 웹 서버로 보냅니다.
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","./file_recieve.asp",false);
xmlhttp.send(xml_dom);
// 서버가 반환한 정보를 표시합니다.
div_message.innerHTML = xmlhttp.ResponseText;
}
</SCRIPT>
서버 측의
동일한 객체를 사용하여 서버 측 업로드 처리 기능을 제공합니다.
<%@ LANGUAGE=VBScript%>
<% 옵션 명시적
Response.Expires = 0
' 변수와 개체를 정의합니다.
희미한 ado_stream
Dimxml_dom
Dim xml_file1
'스트림 객체 생성
set ado_stream = Server.CreateObject("ADODB.Stream")
' 요청 개체에서 XMLDOM 개체를 만듭니다.
xml_dom = Server.CreateObject("MSXML2.DOMDocument") 설정
xml_dom.load(요청)
'바이너리 데이터가 포함된 노드 읽기
set xml_file1 = xml_dom.selectSingleNode("root/file1")
'Stream 개체를 열고 그 안에 데이터를 저장합니다.
ado_stream.Type = 1 ' 1=adTypeBinary
ado_stream.open
ado_stream.Write xml_file1.nodeTypedValue
'파일 저장
ado_stream.SaveToFile "c:tmpupload1.doc",2 ' 2=adSaveCreateOverWrite
ado_stream.close
' 객체 삭제
ado_stream = 아무것도 설정하지 않음
xml_dom = 없음 설정
'브라우저에 정보를 반환합니다.
응답.쓰기 "업로드 성공!"
%>
Stream 개체를 사용하여 데이터베이스의 BLOB 필드에 데이터를 넣을 수도 있습니다.
이 방법을 사용하면페이지 변환이 발생하지 않는다는
이점이 있습니다
.
특별한 구성 요소가 필요하지 않습니다.
여러 파일을 동시에 업로드할 수 있습니다.
이 프로그램은 순수 스크립트로 작성되었으며 HTML 개체의 협력 없이 다른 코드에 쉽게 삽입할 수 있습니다. 이 논리는 COM 표준을 지원하는 모든 언어로 구현될 수도 있습니다.
시스템 보안 고려 사항:
이 방법은 IE5의 보안 수준을 "낮음"으로 설정해야 하기 때문에 내부 네트워크에서만 사용할 수 있습니다. 필수:
스크립트 및 ActiveX 개체를 허용합니다. 이 설정을 사용하면 브라우저가 "myobj = new activexobject(...)"와 같은 JScript 문을 실행할 수 있습니다.
데이터 원본에 대한 도메인 간 액세스가 허용되어야 합니다. 이 설정을 사용하면 클라이언트 측에서 Stream 개체를 사용할 수 있습니다. MS XML DOM 3.0 및 MDAC 2.5도 서버와 클라이언트 모두에 설치되어 있어야 합니다.