태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.
밤하늘의 실제별, 나도 가질 수 있다?!

[Flex/Javascript] 다중 파일 업로더(multi file uploader) 기능을 추가했습니다.

2008/11/14 09:11

 

[공지]이미지나 링크가 깨졌다면 댓글 부탁드립니다.

사용자 삽입 이미지


멀티 파일 업로더 기능이 추가되어서 새로 올립니다.

추가된 내용은 다음과 같습니다.

1. POST, GET 방식으로 Variables를 넘길 수 있도록 함
2. requestHeaders를 추가할 수 있도록 함 (헤더를 보내는 경우 서버측 crossdomain.xml에 allow-http-request-headers-from 설정이 되어야 한다.)
3. contentType(MINE Type)을 지정할 수 있도록 함

이러한 방식은 AS3의 URLRequest에 있는 속성이므로 참고하길 바란다.
사용예는 HTML상의 flashvars 참고하면 된다.


추가적인 설명을 해드리겠습니다.
추가되는 내용에 대한 예제는 첨부된 HTML을 보면 됩니다.

 // multi-file uploader variables
 var flashvars = {
  faServiceJSInstanceName : "uploaderFAService",
  uploadURL : "http://192.168.0.200/upload/uploaderSample.php",
  maxOneFileSize : 10240000, //10MB
  maxFileCount : 10, 
  fileFilterDescriptions : "All Files(*)|Images(*.jpg;*.gif;*.png)|Douments(*.doc;*.hwp;*.pdf)",
  fileFilterExtensions : "*|*.jpg;*.gif;*.png|*.doc;*.hwp;*.pdf",
  uploadDataFieldName : "Filedata",
  buttonImagePath : "fileuploaderbutton.gif",
  method : "post",
  variables: "{'id':'jidolstar','pw':'1111'}", //ex) JSON String형태로 만들되 내부에 큰따옴표(")가 아닌 작은따옴표(')를 써야 한다.
  requestHeaders: null, // ex) "{'Content-Type':'text/html', .... }"  
  contentType : null   ex) "audio/mpeg", "text/html",
http://coderant.egloos.com/3706282 참고
 };
 
위 처럼 파일 업로더에 기본 설정을 넣을 수 있습니다.

  1. faServiceJSInstanceName : 본 파일 업로더는 Flash와 Ajax간에 통신하기 위해 FAService 프레임워크를 사용합니다. JS에서 FAService의 인스턴스명 넣으면 됩니다. 가령, var uploaderFAService = new FAService( fileuploaderSWF ); 로 만들었다면 이 값은 "uploaderFAService"가 됩니다. 이러한 과정이 필요한 이유는 업로더 내(flash)에서 JS로 이벤트를 송출해주기 위함입니다.
  2. uploadURL : 업로드를 요청할 서버측 URL
  3. maxOneFileSize : 1개 파일의 최대 크기. byte 단위로 넣어주세요.
  4. maxFileCount  : 올릴 수 있는 파일 갯수
  5. fileFilterDescriptions : 파일 Filter에 대한 설명, |로 구분할 수 있습니다.
  6. fileFilterExtensions : 파일 Filter로 사용할 확장자. |로 구분하며 *는 전체파일을 뜻합니다.
  7. uploadDataFieldName : 이것은 서버측에 올린 파일을 접근하기 위한 데이타 필드명으로 PHP에서는 $_FILES['Filedata']['tmp_name']; $_FILES['Filedata']['name']; $_FILES['Filedata']['size']; 와 같은 형태로 올라간 파일의 임시명, 파일명, 파일 사이즈를 접근할 수 있습니다.
  8. buttonImagePath  : 버튼 이미지 경로입니다. Flash Player 10부터는 외부에서 Flash의 FileReference의 browse()함수를 직접 호출할 수 없고 Flash 내에 사용자 반응이 있어야 호출 할 수 있습니다. 그러므로 Flash내에 버튼을 만들어 버튼을 누르는 행위로 사용자 반응을 감지하고 browse()함수를 호출할 수 있도록 합니다.

추가된 사항은 파일을 올릴때 다른 정보를 얹어서 보낼 수 있도록 한 것입니다. 서버측 예제는 첨부된 php 파일을 참고하세요.

  1. method는 post 및 get 을 쓰시면 됩니다. 사용하지 않으면 null로 합니다.
  2. variables 는 JSON 형태의 문자열로 만드시면 됩니다. 이 값이 method에서 지정한 get또는 post 방식으로 서버측에 전달됩니다. 단 큰 따옴표(")를 사용하지 마시고 작은 따옴표(')를 사용해야합니다. 사용하지 않으면 null로 합니다.
  3. requestHeaders : 이것도 JSON 형태로 만드시면 됩니다. 따로 request 정보를 서버측에 보내야할 때 설정하시면 됩니다. 사용하지 않으면 null로 합니다.
  4. contentType : 컨텐츠 타입을 문자열로 넣어주시면 됩니다. 사용하지 않으면 null로 합니다.

전체적인 사용예제는 첨부파일에 있는 Release버전을 다운로드 받아 HTML 예제와 PHP 예제를 참고하시면 됩니다. 만약 구현에 대해서 궁금하시다면 source버전을 다운로드 받으시면 되겠습니다.


실행 동영상




동영상에서는 본인이 만든 다중 파일 업로더를 시연해보는 모습을 담았다. 

IE6, FF, Google Chrome 브라우져에서 각각 테스트 해봤다. 

중간에 파일 업로드에 실패하는 것은 지정된 용량 또는 갯수을 초과한 경우이다. 또 Html의 input button을 눌러서 Flash Player 10 환경에서는 안된다는 것도 보여주고 있다. 

동영상에서 보여지는 버튼은 Flex로 만들어진 버튼이다. CSS SWF 또는 일반 이미지(png,jpg,gif,swf)를 붙일 수 있도록 설계했다. 즉 소스를 수정하지 않고도 버튼의 디자인은 입힐 수 있다는 것이다. 

파일이 업로드 중에는 각종 이벤트를 송출하고 있다. 이것으로 실패와 성공 여부를 명확히 알 수 있다. 

아직 첫번째 버전이라 부족한 점이 있지만 계속 개선되어 갈 것이라 생각한다.





readme.txt에 들어간 내용

------------------------------------------
--- 멀티 파일 업로더 (Multi-file uploader) --- 
------------------------------------------

아직 실무에 적용되지 않은 상태입니다만(곧 적용할겁니다.)
사용하는데는 어려움이 많이 없을거라 생각합니다.
공유해서 함께 지식을 넓혀가길 희망합니다.

* author : 지용호 (Yongho, Ji)
* Q&A : jidolstar@gmail.com, http://blog.jidolstar.com
* license : LGPL (수정시에는 소스를 공개합니다. 하지만 그대로 사용하는 것은 사용 출처만 밝혀주세요.)
* 최초제작일 : 2008.10.24
* 최종제작일 : 2008.10.26
* 제작언어 : Adobe Flex 3 
* 제작환경 : Adobe Flex Builder 3 Professional
* 구동환경 테스트 : IE6, FF, google chrome
* 제작배경 
  Flash Player 10이 정식 릴리즈 됨에 따라 Javascript를 통해 FileReference.browse() 메소드를 호출을 방지하도록 되었기 때문에 
    이 방식을 사용한 것을 대체하려고...

* 첨부파일 설명
 1. fileuploader 폴더안에 html 부분처럼 사용하면 되겠다.
 2, php 폴더에는 예제로 만들어진 php소스가 있다. jsp, asp로 비슷하게 만들어 쓰면 되겠다.

* 추가사항
 - 2008.11.14
  1. POST, GET 방식으로 Variables를 넘길 수 있도록 함
  2. requestHeaders를 추가할 수 있도록 함 (헤더를 보내는 경우 서버측 crossdomain.xml에 allow-http-request-headers-from 설정이 되어야 한다.)
  3. contentType(MINE Type)을 지정할 수 있도록 함
  이러한 방식은 AS3의 URLRequest에 있는 속성이므로 참고하길 바란다.
  사용예는 HTML상의 flashvars 참고하면 된다.


* 사용방법
 1. 자바스크립트를 통해 이벤트 핸들러를 등록한다.(FAService Flex-Ajex 통신 브릿지 이용, Flex-JS로 제작됨 , 본인 제작, Flex쪽 소스공개 안 되어 있음)
 2. 파일 업로드를 위한 설정 Flash Vars로 등록 한다.(가령 업로드할 서버 경로, 파일 사이즈, 필터, 버튼이미지 경로등...)
 3. 업로더 SWF를 HTML상에 붙인다. 예제에서는 swfobject.js를 이용했다.
 4. 서버쪽 프로그램을 만든다. 첨부된 php파일을 참고하면 되겠다. asp, jsp든 어떤 언어를 써도 동일하게 만들면 되겠다.
 5. 예제에선 정상적으로 동작하는 경우 textarea에 ready가 뜬다. 이벤트 핸들러가 호출되면 여기에 출력하도록 짜여졌다.
 6. 파일 선택후 ok하면 이벤트는 fileuploader_startAll, (fileuploader_start, fileuploader_step, fileuploader_end), fileuploader_endAll 순으로 진행된다.
    중간에 ()는 여러개의 파일의 경우에 진행상황에 따라서 번갈아가며 호출된다.
 7. 서버 접속이 원할치 않는다면  fileuploader_fail 이벤트가 발생한다.(보안 또는 IO)
 8. 파일 선택을 취소하면 fileuploader_cancel가 발생한다.
 9. 1개의 파일 사이즈가 정해진 크기보다 크면 fileuploader_fileSizeError 이벤트가 발생한다.
 10. 선택한 파일의 갯수가 정해진 갯수보다 크면 fileuploader_fileCountError 이벤트가 발생한다.
 11. 중간에 uploaderFAService.call( "stop", null )을 호출하게 되면 업로드가 최소되고 fileuploader_stopAll 이벤트가 발생한다.
 
* 각 이벤트 파라미터들 
  이벤트 발생시 파라미터들은 JSON Object 형태이다.
 
 - ready  없음
 - fileuploader_startAll : {"totalCount":total count of files, "totalSize":total size of files(bytes) }
 - fileuploader_start : {"filename":file name, "bytesTotal":size of file(bytes)}
 - fileuploader_step : {"filename":file name, "bytesTotal":size of file(bytes), "bytesLoaded":uploaded size of file(bytes)}
 - fileuploader_end : {"filename":file name, "bytesTotal":size of file(bytes), "uploadCompleteData":...}
   여기서 uploadCompleteData는 서버 개발자가 마음대로 값을 바꿀 수 있다. JSON 형태의 String값으로 넘겨주면 프로그램에서는 자동적으로 Object형태로 반환해준다.
 - fileuploader_fail : {"filename":file name, "bytesTotal":size of file(bytes, "msg":error message}
 - fileuploader_endAll : {"failCount": count of files upload failed, "endCount": count of files upload successed , "totalCount": count of files tried to upload }
 - fileuploader_stopAll : {"totalCount":total count of files, "totalSize":total size of files(bytes) }
 - fileuploader_fileSizeError : {"filename":file name, "bytesTotal":size of file(bytes), "maxFileSize": maximum file size(bytes)}
 - fileuploader_fileCountError :{"totalCount":total count of files, "maxFileCount": maximum count of files }
 
* Flash Player 9이하일때는 다음과 같은 방법으로 파일 brawsing을 요청할 수 있다. 하지만 이 방법은 사용을 권장하지 않는다. 
 - uploaderFAService.call('browse',null );

* FAService에 대해 
 - FAService는 Flex-Ajax 통신 모듈입니다.(ActionScript 3 프로젝트로도 사용이 가능) 
 - 여기서는 소스도 함께 공개했습니다.
 - FABridge와 비교할때 최소기능만 사용하도록 만들었습니다.
 - 단순히 addEventListener, removeEventListener, call 만으로 Flex와 Ajax간에 통신합니다.
 - addEventListener은 Flex에서 발생하는 이벤트명, JS이벤트 함수, 우선순위 값이 들어갑니다. 우선순위 값은 같은 이벤트 발생시 호출한 JS이벤트핸들러 함수의 호출 순서를 정합니다. 숫자가 클수록 등록순에 관계없이 먼저 호출됩니다.
 - JS 이벤트 핸들러 함수의 파라미터 값들은 Flex에서 정해서 보내줍니다. Object형이 일반적이지만 Array, Boolean, int, float,String 형등 다양한 형태가 될 수 있습니다.
 - removeEventListener은 기존에 등록한 이벤트 핸들러를 삭제해줍니다.
 - call 함수는 Flex쪽에 "호출명"이 등록되어 있어야만 호출됩니다. 인수값은 Object, Array, Boolean, int, float,String 형등이 모두 가능하며 이 값은 Flex쪽에서 정합니다.
   만약 Flex에서 정한 형태로 만들어지지 않으면 JS Alert 창을 띄우게 됩니다.
 - call 함수는 반드시 ready 이벤트가 발생한 시점 이후로 사용해야합니다. 이전에는 적용되지 않습니다.(스텍을 이용해서 명령을 저장해두었다가 하는 방법도 모색하고 있음, addEventHandler는 그렇게 하고 있음)
 - 등록되어진 이벤트 핸들러, 호출가능한 call 함수 목록등을 반환할 수 있는 함수를 만들 필요가 있다고 생각합니다.
 
 

당신의 별을 찾으세요. 스타플(http://starpl.com)   


 

참고내용

[Flash Player 10]FileReference의 변경된 보안정책과 새롭게 추가된 기능에 대한 나의 생각
swfupload 공식홈페이지

글쓴이 : 지돌스타(http://blog.jidolstar.com/405)

크리에이티브 커먼즈 라이선스
Creative Commons License

Adobe Flash Platform , , , , , , , , ,

Trackback 주소: http://blog.jidolstar.com/trackback/405
  1. 헤에- 지돌스타님은 역시 대단해요~
    심심할 때 소스 분석하면 재밌을 것 같군요+ㅁ+

  2. 감사합니다. ^^
    좋은 정보 함께 공유하면 좋겠네요.

  3. Blog Icon
    혼야

    업로드 잘봤습니다^^ 스타님 덕분에 업로드 소스 참고하여 잘만들었는데..
    다운로드가 문제가 되네요..^^;
    다운로드시 Url 에 대한 문자열에 제약조건같은게 있는건가요??

    "http://aldn.altools.co.kr/altools/ALFTP51.exe" <<-- 예로 이런 문자열을 넣고..
    책의 소스대로 짰는데.. 아무 반응이 없네요..
    조언좀 부탁드립니다^^

  4. Blog Icon
    지돌스타

    혼야님 안녕하세요. 어떻게 만들었는지 모르기 때문에 대답을 드리기가 곤란하네요.

  5. Blog Icon
    혼야

    ^^ 결국엔 삽질이였습니다..^^;
    몇시간 동안 삽질하다가.. 한번 번쩍.. 생각이 들어서 보니깐..
    역시나 삽질인.. ^^; 좋은하루 되세요^^!!

  6. 홋.. 예전에 WoW할때 같이 하시던 분 아이디가 혼야였는데 ㅎㅎ

  7. 으 정말 해결안되어 글남깁니다
    여러파일을 업로드시 문제입니다

    총전송 퍼센트 부분만 남은상태이구요
    step에서 리턴받는 jon 배열문에 전송하고있는 파일의 순번이
    없고. 파일의 업로드 step에 대한. 순서가 일정시간 경과시
    뒤즉박죽 되어버려 총파일 용량에 대한
    현재. 업로드된. 패킷양을. 계산할수없구요
    파일 한개당. 한개씩의. 그래프를 보여주는것을 처리하고 싶습니다

    도움좀 부탁드립니다
    메일발송가능하시면 xellossdh@naver.com 으로 꼭좀부탁드립니다

  8. 정확하게 어떻게 답변을 드려야할지 모르겠군요.

    원리는 매우 간단합니다. 하지만 어떤게 꼬였는지 제가 알수 없는 상황에서 정확하게 답변드리기는 곤란합니다.

    일단 멀티 업로드는 사실 싱글 업로그입니다. FileReferenceList를 통해 FileReference를 얻어와 그 파일의 크기를 계산하고 각각의 파일 크기를 더해 최종 파일 용량을 계산한 뒤에 파일 업로드합니다. 파일 업로드할때 모든 FileReference에 등록된 파일을 올릴 수도 있고 아니면 한개씩 처리해도 됩니다. 제 생각에는 한개 업로드 처리후 다음 업로드 처리하는 것이 네트워크 부하도 줄일 수 있을 것 같습니다.

    건투를 빕니다. ^^

  9. 지돌스타님 답글 감사합니다.

    한가지더 조언을 구합니다 ^^;;

    파일명 :
    1. A
    2. B
    3. C
    4. d
    이렇게 파일을 선택후.. 업로드가 실행되면..
    A,B,C,D 파일에 각각의 순번을 쥐어주고...
    uploaderOnStep(); 에서 받는값에 순번을 추가하는부분입니다..
    .
    .
    .

    즉.. uploaderOnStep(); 에서 받는 값을 추가할수있을까요..

    ###### 현재받는 값 ###############################################
    obj= {"filename":file name, "bytesTotal":size of file(bytes), "bytesLoaded":uploaded size of file(bytes)};
    ###### 받고싶은 값 ###############################################
    obj= {"filename":file name,"filenumber":상위 파일 업로드시 순번,"bytesTotal":size of file(bytes), "bytesLoaded":uploaded size of file(bytes)};

    이렇게 받는다면..
    여러개의 파일을 업로드시에도 각각의 고유번호를 받아와.
    전송된 패킷량을 개별적으로 표현해줄수 있을듯합니다..

    이렇게 않된다면 ;ㅁ; 그래프없는 ...
    그냥 기다려야하는 업로더가 되버리거든요..

    여러개의 파일을 올렸을때..
    가장문제인것이.. A 파일의 받은양을 계산중에..
    무턱대고 갑자기 C파일의 받은양이 티어나와버리니...

    총전송할 양 / 총전송한 양 은 알수있어도..
    현재 전송된 양 을 알수가없군요 ^^;;

    제차.. 답변 감사드리며..
    공개해주신 소스 파일부분은 확인해보지않았네요 ^^;

    쉽게 가능하시면.. 다시한번 조언부탁드리구요..
    소스를 보고 처리가능한것인지.. 확인해봐야겠습니다 ^^

    좋은 하루되시길 바랍니다 (__)

  10. 일단 말씀드릴 수 있는 것은... 다 됩니다.
    제가 이것저것 설명드리는 것은 내용도 많고 어떻게 만드셨는지 소스를 주셔도 분석하고 뭐하면 시간도 많이 걸리므로 ICARUSX님께서 직접 FileReference및 FileReferenceList에 대해서 공부해보시는 것은 어떠실런지요? 레퍼런스를 잘 보시고 그런다음에 생각해보시면 답이 나온답니다. 필요하다면 제 소스를 보셔서 참고하셔도 되고 커스터마이징하셔도 됩니다.

    다시 한번 강조하지만 레퍼런스에 사실 답이 다 숨어있답니다.

  11. 네 감사합니다 (__) 꾸벅;;
    지돌스타님 말씀대로.. FileReference / List 부분 을 확인해보겠습니다 ^^
    감사드립니다 ^^

    p.s : 답변이 무지빠르시군요 ^^ 감사해요

  12. Blog Icon
    jiyun

    다중업로더를 찾는중 딱이거다 생각해서 다운받아 실행 봤습니다

    다른건 아주 잘되는데요
    maxFileCount 이부분을 1로 하고 2개이상 업로드 해도 에러 메시지가 안나오고 파일이 업로드 되버려서요.

    질문 하나만 더할게요
    obj= {"filename":file name, "bytesTotal":size of file(bytes), "bytesLoaded":uploaded size of file(bytes)};
    obj 의 담김 filename, bytesLoaded 대한 값을 가져올수 있는지요 ^^

    조언을 구해보려구 글 남깁니다. ^^

  13. 그런 버그가 있군요. 1이 되는 경우는 생각을 못했다는 ^^; 수정해야겠네요. 바쁘지 않을때 좀 볼께요~

    넘어오는 값들은 모두 Object형으로 받아옵니다.
    obj.filename, obj.bytesTotal 형태로 참고하시면 되겠습니다.