Aug 04 2008

ASP로 AJAX & Cross Domain 해결하기

분류: Tip.Tech 태그: ,, , Heart @ 10:34 오후

Trackback : http://dev.heartsavior.net/archives/170/trackback/

우선 AJAX 개념이 필요하다면 아래 포스트들을 참조…

@ Head Rush Ajax / 동기 & 비동기 + AJAX 기본 흐름
@ ASP + AJAX Step 1 / Step 2 / Step 3

ASP 사이트에서 IIS 외의 웹 서버에서 AJAX 요청을 수행하려고 했지만, Cross Domain 정책에 막혀 실패했다.

구글링을 열심히 해 본 결과, 몇 가지 방법을 찾을 수 있었다. (방법들이 깔끔하게 요약된 포스트가 있어서 링크한다.)

@ Cross Domain Ajax: a Quick Summary

그 중에 Web Proxy 를 사용하기로 결정!
가장 쉬워보였고, 무엇보다 야후 개발자 네트워크에 설명되어 있어서…;;
야후 OpenAPI 를 이런 식으로 사용하길 권장하는 것이니 괜찮은 방법일 것으로 보인다.

@ Use a Web Proxy for Cross-Domain XMLHttpRequest Calls - Yahoo! Developer Network

위의 포스트에는 PHP 로 proxy 를 만들어서 쓰고 있는데, ASP 사이트이기 때문에 ASP 로 proxy 를 만들어 보려 했지만 결국 실력이 딸려 프로그래밍 갤러리에 약간의 도움을 받고(도움 요청글) 코드를 정리해서 완성했다.
(JSP로는 껌일 것 같은데 ASP는 전혀 모르겠다… ‘어플 프로그래머니까…’ 라는 핑계를…-_-;; )

먼저 내가 갖고 있었던, Cross-Domain의 문제를 가지고 있던 코드를 내부 페이지를 호출하도록 변경…

<html>
	<head>
		<title>AJAX TEST - FROM SimpleHttpServer</title>
 
		<script>
			function newXMLHttpRequest() {
				var xmlreq = false;
 
				// IE가 아닌 브라우저
				if(window.XMLHttpRequest) {
					xmlreq = new XMLHttpRequest();
 
				} 
				// IE
				else if(window.ActiveXObject) {
					try {
						// 최근 IE
						xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
					} catch(e1) {
						try {
							// 예전 IE
							xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
 
						} catch(e2) {
							// ALL FAILED !!
						}
					}
				}
 
				return xmlreq;
			}
 
			function getNewID() {
				var req = newXMLHttpRequest();
 
				// CALLBACK 메소드로 getReadyStateHandler를 등록
				var handlerFunction = getReadyStateHandler(req, showNewID);
				req.onreadystatechange = handlerFunction;
 
				// 첫번째 파라미터 - 방식(GET or POST)
				// 두번째 파라미터 - 주소
				// 세 번째 파라미터 - 비동기 여부(true가 비동기, false는 동기)
				req.open("GET","veoh.asp",true);
 
				// POST 이면 헤더도 바꿈
				/*
				req.setRequestHeader("Content-type", 
					"application/x-www-form-urlencoded");
				*/
 
				// 쿼리 스트링이 있을 경우 파라미터로 작성
				req.send(null);
 
			}
 
			function getReadyStateHandler(req, responseJSONHandler) {
				return function() {
					// AJAX에서 데이터를 완전히 얻어온 상태
					if(req.readyState == 4) {
						// 웹 서버에서 코드 200(성공) 을 리턴하였음
						if(req.status == 200) {
							// TEXT(JSON) DATA 가 req.responseText에 들어 있음
 
							// responseJSONHandler 파라미터로 넘어온 함수를 호출
							responseJSONHandler(req.responseText);
 
						} else {
							alert("HTTP error: " + req.status);
						}
					}
				}
			}
 
			// 실제 처리가 이루어지는 함수
			function showNewID(idJSON) {
				// JSON 문자열이 비었으면 에러
				if( idJSON == null ) {
					alert("idJSON is null!!");
					return;
				}
 
				alert(idJSON);
 
				// 일반 문자열에서 JSON으로 변환
				var jsonObject = eval('(' + idJSON + ')');
 
				// error 프로퍼티를 얻음
				var error = jsonObject.error;
 
				if( error == null ) {
					alert("JSON Parse Failed!!");
					return;
 
				} 
				// 성공할 경우 에러 코드 0, 실패할 경우  > 0을 넣어놓도록 되어 있음
				else if( error > 0 ) {
					alert("ERROR Returned!! Error Code : " + error);
					return;
				}
 
				// ID 프로퍼티를 얻음
				var id = jsonObject.ID;
 
				if( id == null ) {
					alert("JSON Parse Failed!!");
					return;
				} else {
					// 얻어온 ID값을 출력
					alert("ID Received!! ID : " + id);
				}
			}
		</script>
 
	</head>
 
	<body>
	<button onclick="getNewID()">새 아이디 얻기</button>
	</body>
</html>

AJAX로 내부 사이트의 proxy 페이지를 호출하며, proxy 페이지로 veoh.asp 를 사용한다.
veoh.asp 에서 외부 사이트의 내용을 넘겨주기만 하면 된다.
Cross-Domain 을 위한 ASP Proxy 페이지(veoh.asp) 는 아래와 같다.

< % @LANGUAGE="JSCRIPT" CODEPAGE="65001" %>
< %
	// Custom Functions
	function $_GET(values) {
		return Request.QueryString(values)!="undefined"?String(Request.QueryString(values)):null;
	}
 
	function echo(values) {
		Response.Write(values);
	}
 
	// Define Timeout Limit
	Server.ScriptTimeout = 10;
 
	Object.prototype.toParam = function(){
		var querystring = [];
		for (var inc in this) {
			if(!this.hasOwnProperty(inc)) continue;
			if (this[inc]!=null) {
				querystring.push(inc + "=" + Server.URLEncode(String(this[inc])));
			} else {
				querystring.push(inc + "=");
			}
		}
 
		return querystring.join("&");
	}
 
	var xmlHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");
 
	// 원래 AJAX 요청을 수행하려던 페이지를 호출한다
	xmlHTTP.open("GET", "http://www.example.com/idrequest", false); //, false, false);
 
	xmlHTTP.setRequestHeader("Content-type", "text/xml");
	xmlHTTP.setRequestHeader("Cache-control","no-cache");
 
	xmlHTTP.send();
 
	Response.Write(xmlHTTP.responseText);
 
	xmlHTTP = null;
%>

이렇게 하면 잘 된다. 흐흐… 문제는, 디버깅이 엄청 어려울 것으로 예상된다는거… 서버를 꺼놓고 테스트해보니까 404가 아닌 500 이 리턴됐고, 더 중요한 것은 exception catch 가 안된다 -_-;;

ps. 프로토타입(prototype.js) 으로 Cross Domain 을 해결하는 포스트가 있긴 한데 테스트는 못해봤음.

@ [PrototypeJS] Cross Domain상의 Ajax 호출


Jun 19 2008

ASP : BLOB 내용을 추출해서 다운로드를 제공하는 코드

분류: Dev.Programming 태그: ,, Heart @ 10:48 오후

Trackback : http://dev.heartsavior.net/archives/147/trackback/

ASP 에서 Oracle BLOB에 저장된 내용을 추출해서 다운로드를 제공하는 코드
(connection string만 변경하면 MS-SQL도 가능)

구글링/데브피아링하다가 발견(출처가 기억나지 않는다…;;)

< % @language=VBScript %>
< % Option Explicit %>

< %
Dim Conn

Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=OraOLEDB.Oracle.1;Password=" & DB_PWD & ";Persist Security Info=True;User ID=" & DB_UID & ";Data Source=" & TNS

Dim rs
Dim Sql
Dim fileName

Sql = "select FILE_NAME, FILE_DATA from TBL1 where ID = 'ID'"
Set Rs= conn.execute(sql)

If rs.eof=false then
fileName = rs(0)

Response.ContentType = "application/octet-stream"
Response.AddHeader "Content-Disposition","attachment; filename=" & fileName

Response.Buffer = True
Response.BinaryWrite rs(1)
Response.End
End If

Rs.close
conn.close
Set conn=nothing
%>

추가로, IIS에서 업로드/다운로드 크기를 조정하는 방법
1. 서비스에서 IIS Admin을 내림
2. c:\windows\system32\inetsrv\MetaBase.xml 편집기로 열어서

AspMaxRequestEntityAllowed=”….”
AspBufferingLimit=”….”

수정할 것(단위 : byte)
3. 서비스에서 IIS Admin, WWW, SMTP, FTP, HTTP SSL 서비스 올림

ps. 코드 하일라이팅 플러그인이 asp는 제대로 출력을 못하네…
(코드 자체는 제대로 나오는데, geshi에서 약간의 오류를 내뱉은 다음에 된다. 음…)


Nov 01 2007

ASP에서 정확한 쿼리인 경우에도 ORA-00907 오른쪽 괄호가 없다고 나온다면…

분류: TroubleShooting 태그: ,, , Heart @ 4:44 오후

Trackback : http://dev.heartsavior.net/archives/69/trackback/

출처 : 데브피아 비주얼 인터데브(ASP) 포럼
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=56&MAEULNo=22&no=129100&ref=129100

오라클 마이그레이션 중에 ASP 단에서 알 수 없는 문제가 생겼다.
분명 SQL Developer로는 실행이 잘 되는 쿼리인데… ASP에서 호출하면 에러가 나는 것이다.
구글로 한참 동안 뒤져봤는데 결국 답을 얻지 못하고 데브피아에서 간신히 찾았다.

답이 의외로 간단하다.

ASP의 DB Connection String을 확인하고 OLEDB라면 ODBC로 변경

당황스러운 해결방안이군…-_-;;

ps. 증상을 말씀하신 분은 ODBC로 바꿔야 된다고 하니 귀찮다며 그냥 쿼리를 바꿔서 해결해 버렸다 -_-;;