블로그 이미지

카테고리

데꾸벅 (194)
Publisher (39)
Scripter (97)
Programmer (1)
Designer (30)
Integrator (18)
Pattern Searcher (4)
News (2)
강좌 및 번역 (3)

최근에 올라온 글

최근에 달린 댓글




데꾸벅 플래쉬 때문에 난관에 봉착하다 (쉿~ 댐~..)

같은 페이지내 파일다운로드 링크를 클릭후 플래쉬의 링크를 클릭하면 다음과 같이
"을(를) 다운로드 할 수 없습니다 지정되지 않은 오류입니다"라는 메세지(IE7)를 만났다.
이런 황당한 경우는 처음이라..





그냥 일반 링크를 getURL("URL주소");를 직접사용하면 상관이 없으나 getURL("javascript:자바스크립트함수()"); 로 호출하면 다음과 같은 에러를 만나게 된다.
문제는 flash player9 로 업데이트 되면서 보안이 강화됐기 때문이란다.. ㅡ.,ㅡ;
adobe가 flash를 framework로 밀기로 작정을 하면서 부터 player업그레이들 하기 싫더라니...
살재 getURL("javascript:alert(1111);");은 브라우저의 주소표시줄에 javascript:alert(1111); 을 친것과 마찬가지 효과를 가진다. 그러나 보안이 강화되면서 이것 또한 막히면서 호출이 되지 않는다.
아래에서 자세히 설명하겠지만 ExternalInterface.call은 actionscript2.0 부터 지원하게 되므로 publishing할때 반드시 actionscript2 를 선택해줘야 한다.



[IE7 에러메세지]
사용자 삽입 이미지



[IE6 에러메세지]
사용자 삽입 이미지
IE6에서는 "보안을 위해 Internet Explorer가 이 사이트에서 사용자의 컴퓨터로 파일을 다운로드하는 것을 차단했습니다. 옵션을 보려면 여기를 클릭하십시오."라는 메세지를 뱉어내네.. ㅡ.,ㅡ; 써글것들...

그레이트김 차장님의 블로그에 처음 포스팅된 글을 볼때만 해도 단순 다운로드 서블릿의 문제일거라 생각했는데 일반 파일을 다운로드후 테스트해도 동일한 결과가 나왔다.
각각 버전별 플래쉬로 다시 퍼블리싱하여 테스트한 결과 Flash8로 퍼블리싱한 것/Flash Player9 만 문제를 일으킨다는것도..


getURL을 이용해서 그런것 같은데...
ExternalInterface.call("외부스크립트메쏘드명","파라미터명");
를 권장한단다.. AS3에서는 getURL을 지원하지 않는다는데..
Adobe에서 플래쉬 플레이어9로 업그레이드 하면서 보안정책상 몇개의 함수를 실행하지 않도록 한것이다.

[레퍼런스참조1, 레퍼런스참조2]





해결책1 :
다운로드 받을때 타겟을 _blank로 잡으면 된다는것...

_top, _self, 다 해봤지만 _blank가 가장 낫다는거..  다만 IE7 이전 버전의 경우 새창이 떠서 문제가 되지만... ㅡ.,ㅡ; 근본적인 문제해결법은 아닌것 같다.

해결책 2 :
아래와 같이 ExternalInterface.call("외부스크립트메쏘드명","파라미터명");을 쓴다. 단 아래 빨간색으로 표시된 부분만 주의해주시길...


HTML소스
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />
<title>lodging_menu</title>
<script type="text/javascript">
function techbugJSFunc(codeStr){
 alert(codeStr);
}
</script>
</head>
<body bgcolor="#ffffff">
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
 width="213" height="592" id="lodging_menu" align="middle">
<param name="allowScriptAccess" value="always" /> 반드시 always로 해주세요.. sameDomain도 안되네요
<param name="movie" value="techbug.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="techbug.swf" quality="high" bgcolor="#ffffff" width="213" height="592" name="techbug" align="middle"
 allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</body>
</html>



ActionScript

link = new Array();
link[1] = "LDG_A00000";
link[2] = "LDG_A01000";
link[3] = "LDG_A02000";
link[4] = "LDG_B00000";
link[5] = "LDG_E00000";
link[6] = "LDG_F00000";
link[7] = "LDG_I00000";
link[8] = "GDE_G00000";
link[9] = "LDG_H00000";
frame = new Array();
frame[1] = "_self";
frame[2] = "_self";
frame[3] = "_self";
frame[4] = "_self";
frame[5] = "_self";
frame[6] = "_self";
frame[7] = "_self";
frame[8] = "_self";
frame[9] = "_self";

numOfMenu = 12 ;
defaultY = 17 ;

max = new Array(0,0,0,0,0,0, 0) ;

_global.active = pageNum ;
_global.subActive = subNum ;
_global.over = active ;

for(i=1 ; i<= numOfMenu ; i++ ) {
 this["menu"+i].defaultY = this["menu"+i]._y ;
 this["menu"+i].bg.onRollOver = function() {
  _global.over = this._parent._name.substring(4) ;
 };
 this["menu"+i].bg.onRollOut = this["menu"+i].bg.onDragOut = function() {
  _global.over = active ;
 };
 if(i != numOfMenu) {
  this["menu"+i].bg.onRelease = function() {
   import flash.external.*;
   ExternalInterface.call("techbugJSFunc",link[this._parent._name.substring(4)]);

   //getURL(link[this._parent._name.substring(4)], frame[this._parent._name.substring(4)]);
  };
 }
 this["menu"+i].bg._height = defaultY ;
 if(i != 1) {
  this["menu"+i]._y = this["menu"+i-1].bg._height + this["menu"+i-1]._y ;
 }
 this["menu"+i].onEnterFrame = function() {
  if(over == this._name.substring(4)) {
   this.direction = "next" ;
   this.nextFrame() ;
  } else {
   this.direction = "prev" ;
   this.prevFrame() ;
  }
  if(Number(this._name.substring(4)) > over) {
   this._y += (this.defaultY + max[over -1] - this._y) / 4 ;
  } else {
   this._y += (this.defaultY - this._y) / 4 ;
  }
  if(this._name.substring(4) != numOfMenu) {
   this.bg._height = this._parent[Number(this._name.substring(4)) + 1]._y - this._y + 10;
  } else {
   this.bg._height = 400;
  }
 };
}
this[numOfMenu].bg.useHandCursor = false;


또한 FlashPlayer9에서 <form>태그내에서 쓸때 버그를 해결하기 위해서는 다음과 같이 작성한다.


 function Flash(id, url, width, height) {    
  var str;    
  str = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="' + width + '" height="' + height + '" id="' + id + '" align="middle">';    
  str += '<param name="allowScriptAccess" value="sameDomain" />';    
  str += '<param name="movie" value="' + url + '" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" />';    
  str += '<embed src="' + url + '" quality="high" bgcolor="#ffffff" width="' + width + '" height="' + height + '" id="'+ id +'" name="' + id + '" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />';    
  str += '</object>';      
  document.write(str);      
 
  //Flash의 ExternalInterface가 Form Tag내에서 오류나는 버그를 해결하는 코드    
  eval("window." + id + " = document.getElementById('" + id + "');");

 }




 이달(2008.4월말)에 다시 보안 업뎃 된다는데 어케 바뀔지는 두고봐야 게따.. 다시 바꿀일이 없길 바라믄서...

[스크립트에서 Flash9 에러방지 ]

// 새로고침시 Flash9 ocx 에러 방지
window.onbeforeunload= function() {
 deconcept.SWFObjectUtil.prepUnload();
}

/*ExternalInterface 관련 함수 시작*/
function cleanup() {
 __flash_unloadHandler = function() {
  externalProbSet = true;
  obj = document.getElementsByTagName('OBJECT');
  for (i=0;i<obj.length;i++) {
   var theObj = eval(obj[i]);
   theObj.style.display = "none";
   for (var prop in theObj) {
    if (typeof(theObj[prop]) == "function") {
     theObj[prop]=null
    }
   }
  }
 }
 if (window.onunload != __flash_unloadHandler) {
  __flash_savedUnloadHandler = window.onunload;
  window.onunload = __flash_unloadHandler;
 }
}
window.onbeforeunload=cleanup;
/*ExternalInterface 관련 함수 끝*/

Post by 넥스트리소프트 데꾸벅(techbug)
, |

파일 다운로드에 따른 getURL로 스크립트 호출하는 플래쉬 링크에러 를 먼저 참조하기 바란다.


플래쉬에서 외부 링크를 걸때 getURL("javascript:스크립트함수호출()") 과 같이 쓰는데
종종 getURL의 경우 링크가 안걸릴때도 있고 같이 페이지내 animated GIF를 멈추게 하는 경우도 있다.
이럴경우 다음과 같이 해보자.

[플래쉬 :]

import flash.external.*;
ExternalInterface.call("스크립트함수명");

[HTML]

javascript:스크립트함수명()


위와 같이 해봤는데도 IE7 / Opera / FF 브라우저 로컬에서 스크립트 엑세스 할경우
보안경고창이 뜨는데 기본적으로 같은 도메인상에 존재해야 getURL함수를 호출할수 있다고 한다. allowScriptAccess를 always를 줘도 마찬가지다..
관련글이 "쇽닥쇽닥"님의 블로그에 포스팅되어 있다.. 참고하도록 하자..


getURL의 단점이라면 위에서 봤던대로..자바스크립트를 호출하면 딸깍거리는 소리가 나기도 하고 gif애니메이션을 멈추게 하는 현상이 있는데.. 이러한 현상은 fscommand를 사용하면 모두 해결할수 있다.

네이버블로그의 FAS에 포스팅된 글(getURL --> fscommand로 바꿀려면)중에 다음과 같은 글이 있어 포스팅한다.


샘플파일



1. 버튼 이벤트에 fscommand( command ,args) 의 형태로 선언한다. 여기서 command 와 args 는 문자열로 전달변수와 전달값이라고 생각하시면됩니다.  command 에서 지정해준 명령키워드를 html 에 선언된 자바스크립트 함수에서 조건으로 찾아 실행할수 있도록 하는역할이죠, args 는 command 명령시 전달될 값으로써 전달할 값이 없다면 "" 빈문자열로 처리해도 됩니다.

2. 퍼블리시 세팅에서 나오는 대화상자에서 format 탭의 html 부분에 체크한후 html 탭으로 가서 첫번째 옵션인 Template 드롭다운 메뉴를 누르면 여러가지 세팅이 나옵니다. 기본값은 Flash Only 인데 Flash with FSCommand 로 선택을 하신후 퍼블리싱 하시면 html 이 생성되며 자동으로 html 안에 fscommand 명령을 처리할수 있는 자바스크립트 함수가 선언이 됩니다.

<script language="JavaScript"> <!-- var isInternetExplorer = navigator.appName.indexOf("Microsoft") != -1; // Handle all the FSCommand messages in a Flash movie. function fscommand_DoFSCommand(command, args) { var fscommandObj = isInternetExplorer ? document.all.fscommand : document.fscommand; // if(command == "msg"){ alert(args) } // } // Hook for Internet Explorer. if (navigator.appName && navigator.appName.indexOf("Microsoft") != -1 &&

navigator.userAgent.indexOf("Windows") != -1 && navigator.userAgent.indexOf("Windows 3.1") == -1) { document.write('<script language=\"VBScript\"\>\n'); document.write('On Error Resume Next\n'); document.write('Sub fscommand_FSCommand(ByVal command, ByVal args)\n'); document.write(' Call fscommand_DoFSCommand(command, args)\n'); document.write('End Sub\n'); document.write('</script\>\n'); } //--> </script>

위에 내용중에서 분홍색음영으로 처리된 부분이 플래시에서 넘겨받은 command 에 따라 실행을 한 예입니다.

그렇다면 플래시안에서 각기 다른 명령어에 따라 다른 결과를 만들어낼수도 있겠죠.. 조건문을 통해서.. ^^



** 보안억세스 설정

이렇게 만 했다고 해서 바로 실행되지는 않습니다.

플래시와 html의 자바스크립트와의 통신을 하는것이기 때문에 플래시8 이후 부터 변경된 보안정책에 의해서 외부스크립트와의 통신이 기본적으로 막아놓은 상태입니다. 그래서 플래시 오브젝트에서 allowScriptAccess 값을 always 로 설정하셔야됩니다.

플래시가 들어가는 오브젝트 태그에 보시면 <param name="allowScriptAccess" value="always" /> 라는 부분과 allowScriptAccess="always"  라는 부분이 있는데 기본값은 sameDomain 으로 되어 있을겁니다. 이것을 always로 바꾸시면 문제없이 자바스크립트를 호출할수 있습니다.

** 플래시 8 부터 제공되는 ExternalInterface.call
플래시 8 부터는 좀더 나이스하게 자바스크립트를 다룰수 있는 액션이 추가되었습니다.

바로  ExternalInterface.call 인데요..  이것과 함께 ExternalInterface.addCallback 을 통해서 플래시에서 자바스크립트함수를... 반대로 자바스크립트에서 플래시안의 함수를 호출할수도 있게 되었습니다. 여기에 대한 자세한 강좌는 왼쪽 스터디 메뉴의 퍼온강좌에서 확인할수 있습니다. 강좌 링크는 다음과 같습니다.

http://cafe.naver.com/fas/901
http://cafe.naver.com/fas/902





Post by 넥스트리소프트 데꾸벅(techbug)
, |