기상청에서 제공하는 날씨정보 XML은 미리 허락된 날씨 정보업체에서만 사용이 가능하다고 하지만 나를 포함해 여기저기서 쓰고 있는 사람이 꽤 많은데도 굳이 막지 않는걸 보면 암묵적으로 사용에 동의하고 있는지도 모르겠다. 그리고 사실 이런건 공공재라고 볼 수도 있는데 막으면 좀 섭섭하지.. 우리나라 기상청 서버 놔두고 외국 날씨 서비스에 가서 기온 가져오는 것도 웃기고..
위에는 쓸데없는 소리였고;; 이 홈페이지 오른쪽 밑에 나오는 날씨 아이콘은 메인페이지를 호출할때마다 기상청에 접속해서 날씨를 읽어온 후 아이콘을 불러오게 된다. 그 과정에서 조금이지만 로딩 시간이 길어지고 내 홈페이지의 트래픽도 증가하는 문제가 있는데 이걸 스크립트로 만들어 사용자에게 떠넘겨버리면 어떨까 싶어 한참전부터 시도해봤지만 결국 오늘로서 포기하고 중간 결과물만 올려둔다.
이 스크립트의 치명적인 문제점은 파이어폭스(아마 넷스케이프도 해당될 듯)에서 기본적으로
XMLHttpRequest() 오브젝트를 이용해서 다른 도메인의 데이터 소스를 가져올 수 없다는데 있다. 다른 도메인에 접근할 수 있도록 대화창을 띄워 Allow 하게 하면 되지만 접속하는 사용자마다 보안경고를 보게될 생각을 하면 끔찍하다;;
여기서는 날씨정보를 담은 XML 문서를
responseText로 받아와 문자열 노가다를 하고 있는데
responseXML을 이용해서 간단하게 코딩을 하고 싶었지만 기상청 서버의 Content-type이
text/xml이 아닌
text/plain으로 잘못 설정돼있어 브라우저에서 XML로 인식하지 못하는 것 같다.
혹시 사용해보거나 테스트하고 싶은 분들을 위해 간단히 설명하자면 함수는
function getWeather(str,
code) { ...
} 하나뿐이니 적당한 곳에 넣어두고
<div id="weatherDiv">날씨 가져오는 중..</div>
<script>getWeather("weatherDiv", 108)</script>
이런식으로 날씨정보가 들어갈 태그에 id를 지정하고, 그 다음에
getWeather()를 호출해주면 된다. 첫번째 인수는 날씨 표시할 곳의 ID, 두번째는 지역 코드(소스 참조). 플래쉬 아이콘은 기상청 사이트에서 직접링크하게 돼있는데 본격적으로 이용해야 한다면 아이콘 정도는 자기 계정에 올려두고 사용하도록 하자.
날씨보기 링크 (소스는 소스보기로..;;)
덧.
집에와서 테스트 해보니 안된다-_-
익스플로러는 보안 설정의 '도메인 간의 데이터 소스 액세스' 옵션을 사용으로 설정하지 않으면 안되고 집의 파이어폭스는 보안 설정을 묻는 대화창이 뜨지도 않는다. 원격지의 소스를 불러오는건 애초에 불가능한건가..
이제 그냥 미련없이 포기-_- (옌장 ㅜㅛㅜ)
덧2.
영 미련이 남아서 도저히;; 그냥 내 호스트를 한번 거치게 해서 원격지가 아닌 로컬 데이터 소스로 접근하도록 변경했다.
getWeather() 함수를 기상청 XML 대신 아래의 페이지를 불러오도록 수정해서
lib.js에 넣었다.
<?
header("Content-Type: text/xml");
$fp = @fsockopen("www.kma.go.kr", 80);
fwrite($fp, "GET /weather/xml/current.xml HTTP/1.0\r\n\r\n");
for($i=0; $i<8; $i++)
fgets($fp, 1024);
while( $buff = fgets($fp, 1024) )
echo $buff;
fclose($fp);
?>
이제 잘 돌아간다. 더이상 손대지 말아야지 -_- (아래는 잘 돌아가는
getWeather() 함수)
function getWeather(str, code)
{
/* 춘천 101
* 백령도 102
* 강릉 105
* 서울 108
* 인천 112
* 울릉도 115
* 수원 119
* 청주 131
* 대전 133
* 대구 143
* 전주 146
* 울산 152
* 마산 155
* 광주 156
* 부산 159
* 제주 184 */
var obj = document.getElementById(str);
var xml;
try { xml = new ActiveXObject("Msxml2.XMLHTTP"); }
catch(e) {
try { xml = new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e) {
try { xml = new XMLHttpRequest(); }
catch(e) { xml = null; }
}
}
if( obj && xml )
{
try {
// 날씨정보가 들어있는 페이지의 경로
xml.open("GET", "/some/where/weather.php?dummy=" + new Date().getTime(), true);
}
catch(e)
{ obj.innerHTML = "Failed"; return; }
xml.onreadystatechange = function()
{
if( xml.readyState == 4 )
{
var body = xml.responseText;
body = body.substring(body.indexOf("<l"), body.lastIndexOf("l>")+2);
local = body.split("<l");
var ta = 0;
var icon = 0;
for(var i=1; i<local.length; i++)
{
var block = local[i];
if( block.indexOf(code) != -1 )
{
var pos1 = block.indexOf("icon");
var pos2 = block.indexOf("\" ", pos1);
icon = block.substring(pos1+6, pos2);
pos1 = block.indexOf("ta");
pos2 = block.indexOf("\">", pos1);
ta = block.substring(pos1+4, pos2);
}
}
if( icon )
{
// 아이콘 파일의 주소
icon = "/some/where/sub" + icon + ".swf";
obj.innerHTML = "<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0\" width=\"25\" height=\"25\"><param name=\"movie\" value=\"" + icon + "\"><param name=\"quality\" value=\"high\"><param name=\"wmode\" value=\"transparent\"><embed src=\"" + icon + "\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" width=\"25\" height=\"25\"></embed></object><br>" + ta + "℃";
}
else
obj.innerHTML = "Error";
}
}
xml.send(null);
delete xml;
}
}