jasu's blog
블로그 메뉴글
[AS3] swf가 임베드된 html 경로 알아내기
Programming/ActionScript 3.0
2008. 12. 25. 02:01
swf가 임베드 되어 있는 html의 도메인 경로를 알아내기 위해서는 아래와 같이 ExternalInterface를 이용하여 자바 스크립트 문법에 도움을 받아 location 경로를 리턴 받을 수 있다.
그러나 이렇게 했을 경우 하나의 문제가 있다.
만약 임베드된 object의 id값을 설정하지 않거나 설정하더라도 동영상 플레이어처럼 여러 개의 swf를 하나의 페이지에 임베드 할 경우에는 오브젝트의 id값이 같기 때문에 ExternalInterface를 이용하여 자바스크립트 함수를 호출할 수 없는 상황이 발생한다. ExternalInterface를 사용할 경우 아래와 같은 경우에는 자바스크립트를 호출할 수 없다.
따라서 하나의 html 페이지에 여러 개의 같은 swf를 임베드 할 경우에는 각각의 object 아이디를 다르게 설정해 주어야 한다. 그러나 상황에 따라서 중첩되는 object태그들의 id를 서로 다르게 부여하기 위해서는 여러 가지 난제가 있을 수 있다. 그렇다면 object 의 id 값을 같게 하더라도 자바스크립트 함수를 호출할 수 있는 방법이 없을까? 위와 같은 상황이라면 IE가 파이어폭스처럼 object id가 같은 상황이라도 ExternalInterface가 자바스크립트 함수를 호출해 줄 수 있을 때까지 기다리거나 ExternalInterface가 위와 같이 호출할 수 없는 상황이 발생하지 않기를 바랄 수밖에 없다. 그렇다고 해결할 수 없는 문제로 남기기에는 플래시가 서운할 것이다. object id가 같아도 ExternalInterface가 자바스크립트 함수를 호출할 수 있도록 만들어 보자.
방법은 ActionScript에서 요긴하게 사용할 수 있는 SharedObject 객체이다. SharedObject객체는 기본적으로 도메인당 최대 100KB의 데이터로 공유 객체를 만들 수 있다. SharedObject의 data속성에는 String, Array, Number, Boolean, ByteArray, XML와 같은 공유 객체를 담을 수 있다.
위에서 언급한 상황처럼 같은 swf가 여러 개 임베드 되어 있고 object id가 같을 경우 IE에서는 첫번째 임베드 되어 있는 swf에서는 정상적으로 ExternalInterface를 통하여 자바스크립트를 호출해 준다. 그러나 아래에 임베드된 swf에서는 자바스크립트를 호출하지 못한다. 따라서 첫번째 임베드된 코드에서 제대로 리턴 받은 경로를 SharedObject를 이용하여 flush(쓰기)를 하고, 반면 ExternalInterface를 통해서 리턴 받은 값이 “null”일 경우에는 SharedObject를 통해서 저장된 기존의 domain 경로를 불러와서 사용하는 것이다.
아래는 그러한 방법으로 처리한 코드 예이다.
위 방법은 그럴듯 하다. 그런데 문제가 있다. 브라우저가 자바스크립트를 호출해 주는 object를 먼저 참조하지 않는다는 것. 따라서 위 방법으로 했을 경우 페이지를 한 차례 재로드해 줘야 제대로 적용이 된다.
결국 object id 값을 서로 다르게 설정하는 것으로 가야만 했다는... 삽질의 길은 멀고도 험하구나...
var locationUrl:String = ExternalInterface.call("document.location.href.toString");
그러나 이렇게 했을 경우 하나의 문제가 있다.
만약 임베드된 object의 id값을 설정하지 않거나 설정하더라도 동영상 플레이어처럼 여러 개의 swf를 하나의 페이지에 임베드 할 경우에는 오브젝트의 id값이 같기 때문에 ExternalInterface를 이용하여 자바스크립트 함수를 호출할 수 없는 상황이 발생한다. ExternalInterface를 사용할 경우 아래와 같은 경우에는 자바스크립트를 호출할 수 없다.
HTML 페이지의 Flash Player 인스턴스에 제공된 이름(object 태그의 id 속성)에 JavaScript에서
연산자로 정의된 하이픈(-)이나 다른 문자가 포함되어 있으면(예: +, *, /, \, . 등) Internet
Explorer에서 컨테이너 웹 페이지를 보면서 ActionScript에서 ExternalInterface를 호출할 수 없습니다.
뿐 만 아니라 Flash Player 인스턴스를 정의하는 HTML 태그(object 및 embed 태그)가 HTML form 태그에 중첩되어 있는 경우에도 ActionScript에서 ExternalInterface가 호출되지 않습니다.
뿐 만 아니라 Flash Player 인스턴스를 정의하는 HTML 태그(object 및 embed 태그)가 HTML form 태그에 중첩되어 있는 경우에도 ActionScript에서 ExternalInterface가 호출되지 않습니다.
따라서 하나의 html 페이지에 여러 개의 같은 swf를 임베드 할 경우에는 각각의 object 아이디를 다르게 설정해 주어야 한다. 그러나 상황에 따라서 중첩되는 object태그들의 id를 서로 다르게 부여하기 위해서는 여러 가지 난제가 있을 수 있다. 그렇다면 object 의 id 값을 같게 하더라도 자바스크립트 함수를 호출할 수 있는 방법이 없을까? 위와 같은 상황이라면 IE가 파이어폭스처럼 object id가 같은 상황이라도 ExternalInterface가 자바스크립트 함수를 호출해 줄 수 있을 때까지 기다리거나 ExternalInterface가 위와 같이 호출할 수 없는 상황이 발생하지 않기를 바랄 수밖에 없다. 그렇다고 해결할 수 없는 문제로 남기기에는 플래시가 서운할 것이다. object id가 같아도 ExternalInterface가 자바스크립트 함수를 호출할 수 있도록 만들어 보자.
방법은 ActionScript에서 요긴하게 사용할 수 있는 SharedObject 객체이다. SharedObject객체는 기본적으로 도메인당 최대 100KB의 데이터로 공유 객체를 만들 수 있다. SharedObject의 data속성에는 String, Array, Number, Boolean, ByteArray, XML와 같은 공유 객체를 담을 수 있다.
위에서 언급한 상황처럼 같은 swf가 여러 개 임베드 되어 있고 object id가 같을 경우 IE에서는 첫번째 임베드 되어 있는 swf에서는 정상적으로 ExternalInterface를 통하여 자바스크립트를 호출해 준다. 그러나 아래에 임베드된 swf에서는 자바스크립트를 호출하지 못한다. 따라서 첫번째 임베드된 코드에서 제대로 리턴 받은 경로를 SharedObject를 이용하여 flush(쓰기)를 하고, 반면 ExternalInterface를 통해서 리턴 받은 값이 “null”일 경우에는 SharedObject를 통해서 저장된 기존의 domain 경로를 불러와서 사용하는 것이다.
아래는 그러한 방법으로 처리한 코드 예이다.
private function getLocationUrl():String
{
var domain:String = String( ExternalInterface.call(" function(){ return document.location.href.toString();}"));
var so:SharedObject = SharedObject.getLocal("location");
if (domain != "null"){
so.data.domain = domain;
so.flush();
}else{
domain = so.data.domain
}
return domain;
}
{
var domain:String = String( ExternalInterface.call(" function(){ return document.location.href.toString();}"));
var so:SharedObject = SharedObject.getLocal("location");
if (domain != "null"){
so.data.domain = domain;
so.flush();
}else{
domain = so.data.domain
}
return domain;
}
위 방법은 그럴듯 하다. 그런데 문제가 있다. 브라우저가 자바스크립트를 호출해 주는 object를 먼저 참조하지 않는다는 것. 따라서 위 방법으로 했을 경우 페이지를 한 차례 재로드해 줘야 제대로 적용이 된다.
결국 object id 값을 서로 다르게 설정하는 것으로 가야만 했다는... 삽질의 길은 멀고도 험하구나...