최근 정말 우연히 Programming Erlang(조 암스트롱, 인사이트)이라는 책을 접했는데, 함수형 언어이고 분산 처리에 적합하게 설계되며 실제로 많이 쓰이고 있다는(!) 것에 감명을 받아 열심히 공부하고 있다. 아직 다 읽지는 못했지만 공부 한 내용을 블로그에 정리해 두려고 한다. (아직 공부한 지 일주일도 되지 않아 코드가 세련되지 못할 수도 있으니 코멘트 부탁드립니다.)
얼랭을 처음 보았을 때의 느낌은 함수형 언어라는 면에서는 LISP와 굉장히 닮았고(실제로 LISP의 많은 철학과 용어를 차용한 것 같다) 문법은 Scala와 많이 유사하다는 것이었다. 일반적으로 C나 Java와 같은 언어로 프로그래밍을 시작한 사람들에게 있어 가장 혼란스러운 부분은
변수가 없다.
반복문이 없다.
일 것이다. 저장해야 할 자료는 모두 함수의 매개변수에 담아 놓고, 반복문을 작성하는 대신 함수를 재귀호출해야 한다는 함수형 언어의 특징이 낯설 수도 있었을텐데, 다행히 나는 Scheme에 조금은 익숙한 상태라 큰 반감 없이 받아들일 수 있었다.
그럼 본론으로 넘어가서 Erlang으로 Factorial을 계산하는 코드를 작성해 보고 실행 시간을 비교해 보고자 한다. 우선, 가장 쉽게 생각할 수 있는 코드는 다음과 같을 것이다.
좋은 코드이지만, Erlang의 장점인 병렬 처리를 충분히 활용하지 못한 코드인 것 같다. 이번에는 병렬 처리를 위해 다음과 같은 코드를 생각할 수 있다.
이 코드는 크게 네 부분으로 구성된다. 우선 fact/1은 작은 문제의 답을 모으는 collector를 띄운 후 문제를 작은 문제로 분할한다. 이 때 작은 문제의 크기는 T의 값에 의해 결정된다. 우선은 T=10000이라는 상수로 두었다. split/4는 문제를 작은 문제들로 분할하는 함수이다. 큰 문제를 T 이하의 크기의 작은 문제 하나와 나머지 크기의 문제로 나눈 후 각각을 푸는 방식이다. 일종의 Divide & Conquer라고 생각할 수도 있겠다. fact/2, fact/3은 먼저 살펴 본 코드와 크게 다르지 않고, 다만 값을 반환하는 것이 아니라 C로 보낸다는 것이 다르다. 마지막으로 collector/3은 작은 문제의 개수를 기억하고 있어서 그 개수 만큼의 답을 얻으면 얻은 답의 곱을 fact/1로 보낸다.
가령 50000!을 계산하고자 한다면, 이 코드는 10000! * (10001 * ... * 20000) * ... * (40001 * ... * 50000)을 계산할 것이다. 싱글 코어라면 오히려 문제를 분할하고 합치는 데에 overhead가 발생하여 성능 저하가 일어나겠지만, 멀티 코어 시스템에서는 작은 문제를 각 코어에서 처리할 수 있으니 더 빠른 성능을 보여 줄 것이라 기대할 수 있다.
실제로, 성능 분석을 해 보면 50000!을 계산하는 데에 처음 제시한 코드는 3095ms, 병렬 처리를 사용한 두 번째 코드는 1059ms가 소요되었다.(i3 머신에서 statistics/1 사용하여 5회 테스트 한 평균) 대략 3배 정도 빠르다는 것을 알 수 있다!
심심하여 큰 수를 자유롭게 계산할 수 있는 또 하나의 언어인 Python으로도 팩토리얼을 구하는 함수를 작성한 후 분석을 해 보았다.
같은 조건에서 5회 테스트 평균을 구해 보았더니 5999ms가 나왔다. 이것은 병렬 처리를 사용하지 않은 Erlang 버전의 2배, 병렬 처리를 사용한 Erlang 버전의 6배 수준이다. 아, Erlang 좋구나.
2008년 1월 19일 이후 작성된 모든 글에 대해서 퍼가는 것을 금지합니다. 퍼가고자 하시는 분은 링크를 달아 주시기 바랍니다.
C에서 코드 길이를 줄이고 깔끔하게 만들기 위해 많이 사용하는 것이 바로 삼항 연산자(ternary operator)이다. ?:으로 구성되는 삼항 연산자의 사용법은 다음과 같다.
result = Condition ? resultWhenTrue : resultWhenFalse;
위 코드는 Condition이 true일 때 result에 resultWhenTrue가 대입되고, Condition이 False일 때 result에 resultWhenFalse가 대입된다. if문을 쓰면 오히려 소스가 보기 싫어지고 이해하기 어렵게 될 때 복잡한 연산 사이에 잘 사용하면 참 간편한 녀석이다.
그러나 Python을 배우면서 삼항 연산자는 공부한 기억이 없다. 코딩을 하면서 색상값을 증가시켜야 하는 부분이 있었다. 색상값이기에 최댓값을 255로 제한해야 했는데, C 같았으면 삼항 연산자를 이용해서 할 터였다. newColor=(oldColor*factor)>255?255:oldColor*factor와 같이 말이다. 그러나 Python에서는 if문을 쓰자니 지저분해지고, 분명히 다른 방법이 있을 것이라는 생각이 들어 찾아보았더니 여러 가지 방법이 존재했다.
2.5부터 지원되는 공식 삼항 연산자
다행스럽게도, Python 2.5부터 기본적으로 공식 삼항 연산자가 지원된다고 한다. C와 비교하면, ?와 : 대신 if, else를 쓰고, 순서가 조금 바뀌었다.,
result = resultWhenTrue if Condition else resultWhenFalse
읽었을 때 자연스럽게 의미가 있는 문장으로 읽히는 것은 좋지만 resultWhenTrue와 resultWhenFalse 사이에 Condition이 들어 있어 가독성 면에서는 조금 부정적인 면이 있지 않나 생각한다.
튜플을 이용한 방법:
Python에서 True는 1이고, False는 0이다. 따라서 조건을 시퀀스의 인덱스로 사용할 수 있다.
result = ( resultWhenFalse, resultWhenTrue )[ Condition ]
형태는 간결하지만 처음 보는 사람의 경우 그 의미를 이해하기까지 시간이 걸린다. 또한 resultWhenFalse와 resultWhenTrue를 미리 계산해 놓기 때문에 미리 계산하면 안되는 경우(조건에서 인덱스의 범위를 검사하여 범위 안에서만 원소에 접근해야 하는 경우 등)에는 부적절하다.
논리 연산자를 이용한 방법:
x and y는 x를 먼저 실행한 후 결과가 False이면 x를 리턴하고, True이면 y를 계산한 후 이를 리턴한다. x or y는 x를 먼저 실행한 후 결과가 True이면 x를 리턴하고, False이면 y를 계산한 후 이를 리턴한다. 자세한 설명은 Documentation에 잘 나와 있다. 이와 같은 특성을 이용하면 논리 연산자로도 삼항 연산자를 구현할 수 있다.
result = Condition and resultWhenTrue or resultWhenFalse
만약 Condition이 True라면 and 연산자는 resultWhenTrue를 리턴할 것이다. resultWhenTrue가 True라면 or 연산자는 resultWhenTrue를 리턴하므로 결과적으로 전체 문장은 resultWhenTrue를 리턴한다. 만약 Condition이 False라면 and 연산자는 Condition, 즉 False를 리턴할 것이다. or 연산자는 앞에 있는 문장이 False이므로 뒤에 있는 resultWhenFalse를 리턴하므로, 전체 문장은 resultWhenFalse를 리턴한다. 이 방법의 큰 문제는 resultWhenTrue가 항상 True일 때에만 사용할 수 있다는 것이다. 만약 resultWhenTrue가 False라면 Condition이 True일 때 or 연산자는 resultWhenTrue 대신 resultWhenFalse를 리턴할 것이다. 이를 해결하기 위해 약간의 수정을 한다.
result = (Condition and [resultWhenTrue] or [resultWhenFalse])[0]
resultWhenTrue를 담고 있는 리스트는 항상 True이므로(원소 개수가 1개 이상이면 True) 둥근 괄호는 resultWhenTrue와 resultWhenFalse 중 하나를 원소로 가지는 리스트를 리턴할 것이고, 이의 첫 번째 원소를 취하면 우리가 원하는 값을 얻을 수 있다. 논리 연산자의 특성상 이 방법은 조건이 거짓일 때에는 아예 resultWhenFalse를 계산하지 않는다.
2.5버전부터는 새로운 연산자가 생겨 굳이 편법을 사용하지 않아도 되게 되었지만 편법을 쓴 사람들이 쓴 다른 코드를 읽을 때에는 조금 도움이 되지 않을까.
2008년 1월 19일 이후 작성된 모든 글에 대해서 퍼가는 것을 금지합니다. 퍼가고자 하시는 분은 링크를 달아 주시기 바랍니다.
프로그램을 개발하던 도중 10진수로 표현된 Unicode, 즉 &#으로 시작하여 10진수 Unicode가 있고 세미콜론(;)으로 끝나는 문자를 출력해야 할 상황이 생겼다. Javascript에서 문자열 변수 안에 있는 문자열은 '並ぶ'와 같았으며, 그냥 단순히 출력할 경우 코드 부분이 변환되지 않고 그대로 출력되는 문제점이 있었다.
10진 Unicode를 코드에 해당하는 실제 문자로 변환하기 위해서는 String.fromCharCode라는 Javascript 함수를 써야 한다. 그러나 이 함수는 문자 코드를 문자로 변환하는 역할만 할 뿐 문자 코드가 섞여 있는 문자열을 변환하는 기능은 없었다.
그래서 다음과 같은 함수를 만들었다.
str에 변환하고자 하는 문자열을 넘기면 정규식을 이용해 십진 유니코드를 파싱한 뒤 이를 실제 문자로 치환하여 리턴한다.
2008년 1월 19일 이후 작성된 모든 글에 대해서 퍼가는 것을 금지합니다. 퍼가고자 하시는 분은 링크를 달아 주시기 바랍니다.
필자는 지식IN에서 지식인 이용규정에 조금이라도 어긋나는 글을 보면 즉각 신고하는 편이다. 오늘도 지식IN을 서핑하다가 파일공유 사이트를 홍보하는 답변을 보고 신고를 하기 위해 '신고' 버튼을 눌렀다. 하지만 볼 수 있었던 것은 신고 창이 아닌, '페이지를 찾을 수 없습니다' 라는 에러 페이지였다. 순간 인터넷이 끊긴 것인가 하고 다른 사이트에 접속해 보았지만 접속은 원활히 잘 되었다. 네이버가 죽었나 싶어서 다른 네이버 페이지에도 접속해보았지만 별 문제를 찾을 수 없었다. 마지막으로 '신고' 버튼의 링크를 확인해 보았더니, 다음과 같은 링크로 연결되었다.
하지만, 신고 창의 '제목' 란과 '작성자 ID' 란은 공란이었다. 분명 제목과 작성자 ID가 떠야 할 터인데 말이었다. 이상하다 싶어 질문의 작성 날짜를 확인했다. 작성 날짜는 9월 18일로 되어 있었다. 바로 해당 디렉토리의 해결중 질문 DB를 뒤져보았다. 하지만 가장 오래 전에 작성된 질문이 9월 18일의 질문이었고, 더 이전의 글은 이미 '미해결'이나 '완료'로 넘어간 상태였다.
그 때 필자가 발견한 것은 광고 답변은 진짜 답변이 아닌 가짜 답변이었다는 것이다. 순간 섬뜩함을 느꼈다. 즉, 질문 페이지는 다음과 같았다.
'한글오류 긴급패치 다운로드' 부분이 파일공유 사이트로 연결되는 링크이다.
위쪽의 질문과 답변은 조작된 것이었고, 아래쪽에 하나 더 있는 질문부터가 진짜 질문과 답변이었다. 실제로 위쪽의 질문과 답변의 작성자 아이디에는 링크가 걸려 있지 않았으며, 답변 수도 실제 답변 수와 일치하지 않았다.
누가 어떻게 이런 짓을 했을까 하며 소스를 가만히 살펴 보았다. 신기한 것은 분명 광고 내용은 페이지의 가장 위쪽에 있는데, 소스 상에서는 광고 내용이 가장 밑에 있는 것이었다. 가장 밑에 있는 답변을 보았더니 아무 내용도 없었다. 수상한 일이었다.
확실히 어떻게 렌더링이 되는 것인가 하여 Firefox의 부가기능인 Firebug의 Element Inspector를 이용하여 구조를 살펴 보았다.
결과는 정말 이상했다. 소스상에서는 가장 아래쪽에 있는 셀의 내용(가짜 질문 및 답변)이 렌더링이 된 후에는 테이블의 바로 위에 와서 붙는 것이었다.
순간 브라우저의 렌더링 버그라는 생각이 들어 소스를 가만히 분석해 보았더니, 셀 안쪽이 다음과 같았다.
<td> <td> </tr> <div>가짜 질문 및 답변</div> </td>
중간에 <td> </tr>이라는, 구조에 어긋나는 태그가 들어 있었다. 이것이 버그를 유도하는 것일 것이라는 생각이 들어서 간단한 페이지를 작성해서 테스트를 해 보았다. 가로 세로 2개의 셀이 있는 테이블인데, 우측 하단의 셀 안에 <td></tr>의 태그를 넣은 것이었다. 결과는 놀라웠다.
보이는 결과와 같이, 우측 하단의 셀의 내용이 테이블 위쪽으로 나왔다.
결국, 가짜 질문과 답변은 소스만 있는, 그럴듯하게 보이는 것들일 뿐이고, 실제 광고의 작성자는 가장 아래의 답변을 작성한 사람이었던 것이다. 광고를 하는 사람은 가짜 답변의 작성자 ID를 조작하고 신고 링크를 무력화시킴으로써 좀 더 오랫동안 삭제당하지 않고, 진짜 자기 ID를 들키지 않을 수 있었을 것이다.
네이버 측도 이를 알고 있었던 것인지, 필자가 포스팅을 하려고 준비하는 순간 해당 답변을 삭제했다. 다행히도 원래 보고 있던 페이지를 닫지 않아 스크린샷을 찍을 수 있었다.
2008년 1월 19일 이후 작성된 모든 글에 대해서 퍼가는 것을 금지합니다. 퍼가고자 하시는 분은 링크를 달아 주시기 바랍니다.
Runtime시에 실시간으로 자바스크립트로 스타일시트를 변경하기 위해서는 두 가지 방법이 존재한다. 두 개의 스타일시트 클래스를 만들어 놓고 Object의 Class 속성을 변경하는 방법이 가장 많이 쓰이는 방법이나, 이는 변경의 폭이 매우 제한적이다. 또 다른 방법은 스타일시트 자체를 변경해 주는 것이다. 두 방법 모두 브라우저 간에 방법이 다르기 때문에 Cross Browsing 문제에 대해 신경을 써야 한다. 본 포스트에서는 두 번째 방법에 대해서만 설명한다.
개체의 width는 30으로, height은 15로 조절하고 싶을 때
IE의 경우 obj.style.cssText="width:30px; height:15px;";
비 IE 브라우저의 경우 obj.style.width="30px;"; obj.style.height="15px;";
IE가 좀 더 편한 듯 보이나, 위 예제 후 width를 제외한 height만 다시 변경할 경우를 보자.
개체의 height만 25로 조절하고 싶을 때
IE의 경우 obj.style.cssText="width:30px; height:25px;";
IE와 비IE 브라우저 간 차이를 보이는 Stylesheet 중 하나가 투명도에 관련된 Stylesheet이다. 일반적으로 투명도를 조절할 때 스타일시트를 다음과 같이 써 준다.
opacity:0.80; filter:alpha(opacity=0.80);
사실 이 코드 자체가 브라우저 간 호환성을 고려한 코드이다. 왜냐하면, opacity라는 속성은 비IE 브라우저에서만 작동하고, filter라는 속성은 IE에서만 작동하기 때문이다. 또한 Stylesheet는 정의되지 않는 속성 이름이 있어도 오류를 내지 않고 무시하고 넘어가기 때문에 이와 같이 써 주어도 무방한 것이다.
하지만 자바스크립트로 투명도를 조절해야 할 때에는 어차피 스타일시트를 자바스크립트로 조작하는 방법이 브라우저간 차이가 있기 때문에 각각에 맞는 스타일만 써 주어도 될 것이다. 다음과 같다.
컴퓨터에서 Cross 라는 말이 붙으면 호환이 된다는 의미이다. Cross-Language라고 하면 언어 간 호환이 되는 패키지나 클래스를 일컫고, Cross-Platform이라고 하면 플랫폼간 호환이 가능한 것을 말한다. 마찬가지로, Cross-Browsing이라는 브라우저간 호환이 되도록 하는 것을 일컫는다.
Apec Cyber Academy의 과제 중 하나로 학교와 고장, 팀원을 소개하는 웹 페이지를 작성하게 되었다. 그런데 여기서 제시한 '잘 만들어진 페이지'의 기준 중 하나가 '모든 브라우저에서 정상적으로 작동한다'이다. 즉, Cross-Browsing이 얼마나 잘 되었느냐가 채점 시 반영된다는 것이었다. 때문에 페이지 하나를 만들면서도 Cross-Browsing 문제에 굉장히 예민해질 수밖에 없었다.
많은 사람들이 아직까지 Cross-Browsing에 대해 많은 지식이나 개념을 갖지 못하고 있는 것이 사실이다. Cross-Browsing은 브라우저를 크게 Microsoft Internet Explorer와 그 이외의 브라우저, 두 개로 나누었을 때 둘 간의 호환이 많은 부분 되지 않기 때문에 이를 해결해 주는 것이다. 역시 문제는 MS IE이다. IE 7로 넘어 오면서 상당 부분 개선된 것은 사실이나 아직 Opera나 Firefox의 표준 준수율을 따라가기에는 그 거리가 굉장히 멀다. 시장 지배력은 가장 큰 브라우저로서 페이지 제작과 이용의 편의를 위해 MS는 각성하고 하루 뻘리 표준 준수율을 높여야 할 것이다.
표준이 단순히 많이 사용하는지 여부를 놓고 제정된다면 표준에 의미가 사라집니다. 표준이라는 것은 정말 다양한 요인을 고려하여 정해집니다. 가령, 과거에 쓰이던 기술과의 호환성, 미래에 개발 가능성이 있는 기술들, 장애인의 접근성, 유지·보수의 편리성 등 다양한 요인들을 분석하여 가장 잘 부합되는 것을 수십차례의 회의를 거쳐 정하는 것이 표준입니다. 그런데 MS는 시장 지배력만을 믿고 지나치게 표준을 무시하고 있습니다. 그러한 부분에서 MS는 반성을 해야 할 것입니다.
method 통신의 방법을 설정한다. "POST"와 "GET", "PUT" 중 하나를 넘겨줄 수 있는데, "POST"의 경우 실제 http 자체에 내용을 넣어 전달하는 것이고, "GET"의 경우 '?' 기호와 '&' 기호를 이용하여 주소에 여러 변수의 값을 담아 넘겨주는 방법이다. "PUT"의 경우 거의 쓰이지는 않는 방법이다.
url 통신할 파일의 주소를 적어준다. 절대 경로와 상대 경로 둘 다 상관 없지만 주의할 점은 같은 서버 내에 있어야 접근이 허가된다는 것이다.
asynch 통신의 동기/비동기 여부를 결정한다. true일 경우 비동기 통신, false일 경우 동기 통신이 된다. 기본값은 true, 즉 비동기 통신이다. AJAX의 큰 장점 중 하나가 비동기 통신이므로 주로 true로 사용한다.
username, password 해당 페이지에서 username과 password를 요구한다면 이 인자를 통해 username과 password를 전달한다.
27라인에서는 콜백 함수를 설정하고 있다. 콜백 함수란, 직접 호출하지 않아도 특정 이벤트에 자동으로 호출되는 함수를 말한다. onreadystatechange라는 이벤트에 CallBack()이라는 함수를 할당함으로써 onreadystatechange 이벤트가 발생할 경우 자동으로 CallBack() 함수가 호출된다.
28라인의 send() 함수는 실질적으로 통신을 하는 함수이다. 인자로는 전달할 데이터를 넣어주는데, "GET" 방식에서는 null을, "POST" 방식에서는 전달할 데이터를 넣어주면 된다.
서버에서 응답하기
이렇게 하여 서버로 요청이 넘어가면 서버에서는 time.php 파일을 열어 응답을 한다. 응답은 일반 웹 페이지를 뿌리는 것과 똑같이 하면 된다. 즉, php로 응답을 할 경우 echo로 뿌려 준 모든 소스코드가 응답이 된다.
time.php에서는 GetServerTime.html에서 요청을 전달받고 바로 응답을 한다. header 함수의 경우 응답 http의 헤더를 설정하는 부분인데, 꼭 응답의 헤더에서 Content-Type, 즉 mime을 text/xml로 설정해야 클라이언트에서 XML 데이터로 받아 처리할 수 있다. 그렇지 않을 경우 XML 데이터임에도 불구하고 XML로 인식을 하지 못하게 된다.
ReadyState
XMLHttpRequest 객체를 사용하는 모든 과정에서 이 객체의 속성 중 하나인 readystate가 계속 변하게 되며, 변할 때마다 onreadystatechange라는 이벤트를 발생시킨다. readystate는 다음과 같이 5가지의 값을 가질 수 있다.
0 객체는 생성되었으나 open 함수는 호출되지 않음 1 open 함수는 호출되었으나 send 함수는 호출되지 않음 2 send 함수는 호출되었으나 아직 서버로부터 응답이 오지 않음 3 서버로부터 응답이 일부만 도착함 4 서버로부터 모든 응답이 도착함
즉 실제로 응답을 처리해야 하는 시점은 readystate가 4인 때이다.
onreadystatechange 이벤트의 콜백 함수로 CallBack() 함수를 설정했으니 readystate가 0~4로 바뀔 때마다 CallBack() 함수가 호출된다. CallBack() 함수에서는 매번 readystate의 값을 검사하여 4일 경우에만 응답을 처리하면 된다.
하지만 readystate가 4인 경우에도 올바르지 않은 응답이 올 수 있다. 가령, 접근 권한이 없어 접근하지 못했을 때에도 readystate는 4가 될 수 있다. 이 때에는 XMLHttpRequest의 status 속성을 검사하면 된다. status는 성공적인 응답이 왔을 때에 200으로 설정되므로 이를 검사한다.
응답 처리하기
이렇게 readystate==4 && status==200의 조건을 만족했을 경우 서버로부터 성공적인 응답이 도착한 것이므로 xhr에는 응답이 저장된다. 이 응답은 두 가지 방법으로 접근할 수 있다.
첫 번째 방법은 xhr.responseText로 접근하는 것이다. 서버에서 XML 데이터가 아닌 Text 데이터를 리턴했을 경우 사용한다. XML을 리턴했더라도 이를 Text의 형태로 받고 싶다면 이를 이용한다.
두 번째 방법은 xhr.responseXML로 접근하는 것이다. 이 방법은 응답의 Content-type이 text/xml인 경우에만 성공적으로 처리된다. 이 방법은 DOM Object의 형태로 XML 문서에 접근할 수 있어 매우 편하다. 또한 AJAX 자체가 본래 XML을 사용하도록 만들어 진 것이므로 주로 이 방법을 사용하게 된다.
DOMDocument
DOMDocument란, XML 데이터를 효과적으로 제어/조작하기 위하여 고안된 객체이다. XML 데이터를 통째로 읽어 메모리에 트리의 형태로 저장해 놓고 다음의 명령어들을 통해 검색/추가/제거/수정 등의 작업을 할 수 있다. element라는 DOM Object가 존재한다고 가정하고 설명한다.
접근 element.childNodes : element의 모든 자식 노드를 배열로 반환한다. element.firstChild : element의 첫 번째 자식 노드를 반환한다. element.lastChild : element의 마지막 자식 노드를 반환한다. element.parentNode : element의 부모 노드를 반환한다. element.nextSibling : element의 다음 형제 노드를 반환한다. element.previousSibling : element의 이전 형제 노드를 반환한다. element.nodeValue(=data) : element의 값을 반환한다. element.hasChildNodes(); : element가 자식노드를 가지면 true, 가지지 않으면 false를 반환한다. element.getAttribute(name); : element의 attribute 중 이름이 name인 attribute의 값을 반환한다.
검색 element.getElementsByTagName(tagname); : 이름이 tagname인 모든 노드를 배열의 형태로 반환한다. element.getElementById(tagID); : ID가 tagID인 노드를 반환한다.
추가 document.createElement(tagname); : tagname의 이름으로 새로운 노드를 생성한다. document.createTextNode(text); : text의 값으로 새로운 텍스트 노드를 생성한다. element.appendChild(child); : child를 맨 마지막 자식 노드 뒤에 추가한다. element.insertBefore(new, target); : new를 target 바로 앞에 추가한다.
제거 element.removeChild(child); : element의 자식 노드 중 child를 삭제한다.
변경 element.replaceChild(new, old); : element의 자식 노드 중 old를 new로 대체한다. element.setAttribute(name, value); : element의 속성 중 이름이 name인 속성의 값을 value로 설정한다. element.removeAttribute(name); : element의 속성 중 이름이 name인 속성을 삭제한다.
마무리
기본적으로 서버와 통신하는 방법을 알아보았다. 사실 위의 소스코드를 그대로 실행하면 시간이 바뀌지 않는다는 것을 알 수 있다. 이는 인터넷 임시 파일이 생성되어 분명 페이지가 바뀌었음에도 불구하고 컴퓨터에 저장된 임시 파일을 읽어들여서 바뀌지 않은 내용을 보여주기 때문이다. 이 때에는 요청하는 주소를 계속 변화시키기 위하여 주소에 랜덤값을 같이 넘겨 주는 것이 좋다. 예를 들어 다음과 같다.
url="time.php?key=" + Math.random();
위와 같이 하면 매번 다른 주소로 요청이 넘어가기 때문에 저장된 임시 페이지를 읽어오지 않아서 매번 다른 값을 볼 수 있다.
2008년 1월 19일 이후 작성된 모든 글에 대해서 퍼가는 것을 금지합니다. 퍼가고자 하시는 분은 링크를 달아 주시기 바랍니다.
AJAX는 Asynchronous JAvascript & XML의 약자로, 말 그대로 자바스크립트와 XML을 이용하여 서버와 비동기적으로 통신하는 것을 일컫는다. 이를 이용하면 좀 더 다이나믹한 웹 페이지를 꾸밀 수 있게 된다.
일반적으로, 서버와 통신하기 위해서는 한 번의 페이지 이동을 거쳐야 한다. 왜냐 하면 서버측 프로그램은 페이지가 바뀔 때 호출이 되고, 이 때 서버의 정보를 얻어올 수 있기 때문이다. 물론 HTML등의 단순한 문서는 서버측의 프로그램이 필요 없을 수도 있겠지만, DB에 Access하는 페이지의 경우 일반적으로는 한 번의 작업을 할 때마다 페이지를 이동하여 서버측 프로그램을 호출해야 한다.
하지만, AJAX를 이용하면 서버 작업 시 페이지 이동이 불필요하게 되어서 사용자로 하여금 훨씬 편하게 사이트를 이용할 수 있게 한다.
AJAX를 이용한 대표적인 사이트를 꼽으라면 구글 맵스를 들 수 있을 것이다. 이는 프로그램으로 나와 있던 Google Earth를 웹 상으로 옮겨놓은 것이라고 생각하면 된다.
AJAX가 구현된 대표적인 사이트로 꼽히는 'Google Maps'의 페이지 모습이다.
처음 보는 사람이라면 '이거 뭐 다른데서 서비스하는 지도랑 똑같잖아?'라고 생각할 수도 있다. 하지만 분명히 큰 차이점이 있다. 다른 곳은 이용할 때 ActiveX 플러그인을 설치할 것을 요구한다. 하지만 구글 맵스는 어떠한 설치도 필요없다. 이것이 구글 맵스의 가장 큰 장점인 것이며, AJAX의 장점을 여실히 보여주는 예이다.
ActiveX가 없는 순수한 웹페이지인데도 페이지 전환이 없이 깔끔하게 지도를 표시하고 있다.
AJAX를 이용하면 어떤 것이 가능한 것인지 충분히 볼 수 있었다고 생각된다.
AJAX의 핵심요소는 XMLHttpRequest와 DOM이다.
XMLHttpRequest : 페이지 전환 없이 서버로 Http를 이용하여 정보를 전달하고 받아오는 자바스크립트 객체이다. 본래 IE가 처음 지원하였으나 현재는 대부분의 브라우저가 지원하고 있다. DOM : XML 데이터를 관리하는 객체이다. XML 자료가 주어지면 몇 가지 함수를 통해 파싱, 추가, 삭제, 수정 등을 자유롭게 할 수 있도록 도와준다.
기본적인 원리를 간단히 설명하자면, XMLHttpRequest라는 객체에 여러 가지 정보를 담고 서버로 이를 전송한다. 그러면 서버가 이를 받아 처리를 한 후 그 결과값을 다시 클라이언트로 전송한다. 클라이언트는 서버에서 받아온 결과값을 이용하여 실시간으로 페이지를 갱신하게 된다.
태터툴즈의 자동 저장기능에 감사드립니다. 한 번 잘못 눌렀는데 다행히 다 저장되어있네요.. 저도 아직 AJAX를 공부하고 있는 입장이지만, 공부해 나가면서 계속 포스팅하겠습니다.
2008년 1월 19일 이후 작성된 모든 글에 대해서 퍼가는 것을 금지합니다. 퍼가고자 하시는 분은 링크를 달아 주시기 바랍니다.
댓글을 달아 주세요
좋구나.