2014년 12월 11일 목요일

jQuery에서 ajax() 호출 시 response가 항상 똑같은 경우 (ajax GET, PUT method의 caching 방지)

일부 브라우저에서는 jQuery ajax로 GET, PUT method 호출 시
받아온 결과값이 항상 일정하거나 PUT이 제대로 먹히지 않는 경우가 있음.

원인을 몰라 난감하던 차에 아래 사이트 발견

selfesteem님의 [jquery] $.ajax 에서 GET일때 cache가 남는경우...
http://selfesteem.tistory.com/entry/jquery-ajax-%EC%97%90%EC%84%9C-GET%EC%9D%BC%EB%95%8C-cache%EA%B0%80-%EB%82%A8%EB%8A%94%EA%B2%BD%EC%9A%B0

http://stackoverflow.com/questions/367786/prevent-caching-of-ajax-call


위의 사이트를 참조하여
ajax로 GET method 호출 시

cache : false, 를 항상 추가하고

ajax로 PUT method 호출 시

URL + '?' + $.now() 로 해결함.


그리고 이 문제는 Galaxy S2에서 항상 재현된다.


2014년 12월 10일 수요일

jQuery ajax() 사용시 jqXHR의 error code가 0일 경우

jQuery를 사용하여 Ajax를 사용해서 REST API를  잘 호출 하고 있었으나
종종 앱 종료 시 호출되는 Ajax 호출이 error로 처리 되어
서버에서 종료 처리가 되지 않고 앱이 그냥 종료되는 상황이 발생함.

Ajax 호출 코드는 다른 곳에서도 잘 실행되던 거라
종료 처리를 하는 DELETE method가 문제인가 계속 확인을 하던 중
아래 링크들을 확인함.

http://cricri4289.blogspot.kr/2013/10/jquery-ajax-error-code-0.html
http://stackoverflow.com/questions/14313283/jquery-ajax-jqxhr-status-is-always-0


일반적인 경우는 Ajax 호출 후 바로 페이지가 새로고침이 되거나 전환 될 경우
Ajax 호출이 실패하고 error code가 0으로 리턴 될 경우가 있다고 함.
그게 아니라면 실제로 서버 연결이 안되거나 할 경우이고.

암튼 나의 경우는 Ajax 호출 후 바로 앱을 닫아 버려서
미처 Ajax 호출이 완료되지 않은 상태에서 앱이 종료되어 문제가 되었던 경우라서
Ajax 호출이 완료 되어 callback에서 종료 처리를 하고
혹시나 몰라 timeout을 사용해서 종료 처리를 하도록 함.

2014년 11월 24일 월요일

JavaScript Timer가 어떻게 동작하는가?

얼마전 JavaScript timer가 궁금해서 찾던 중 아래 글을 발견하고
JavaScript timer의 동작에 대해서 알게 되었음.

How JavaScript Timers Work, John Resig
http://ejohn.org/blog/how-javascript-timers-work/

작성된지는 꽤 오래전 글이라 다른 블로그에서 잘 다루고 있음.
http://holdonj.tistory.com/9


내용을 대충 정리하면 아래 두 함수는 JavaScript 코딩 중에 일정 주기로 코드를 실행되게 할 때 사용하는 함수들이다.

- setTimeout(fn, delay) : delay 이후 실행되는 single timer
- setInterval(fn, delay) : delay 마다 실행되도록 하는 주기적인 timer

함수의 효과는 동일하게 느껴 지지만 실제 사용할 때는 아래 사항들을 알고 사용해야 한다.

- JavaScript timer의 delay는 보장되지 않는다.
- JavaScript 코드는 실행가능한 조건에서 실행되며 이는 웹브라우저가 single thread상에서 비동기적 event들(mouse click, timer 등)을 처리하기 때문이다.

이를 아래 그림을 통해 자세히 설명 하고 있다.





위 그림 내에서
왼쪽의 숫자들은 시간(ms단위)를 의미하고, 오른쪽은 비동기적 event들을 나타내고,
중간의 블럭들은 실행되는 JavaScript 코드들이다.
 * JavaScript 코드들은 single thread 상에서 처리되므로 하나의 한 block만 처리된다.

시간 순서대로 보면 

- 20ms 내에서는 순차적으로 timer, mouse click, interval event들이 발생된다. 
 . mouse click 발생 시 event cb(callback)를 Queue에 등록한다.
 . 10ms 이후 등록된 timer cb을 실행되려 하지만 아직 JavaScript 코드가 실행중이므로 Queue에 등록한다. (Queue : mouse click event cb, timer cb)

- 20ms 전, JavaScript 코드가 완료되면 Queue의 첫번째 mouse click event cb을 처리한다.
 . 20ms 시점에 mouse click event cb처리 도중 interval cb이 실행되려 하지만 실행할 수 없어 Queue에 등록한다. (Queue : timer cb, interval cb)

- 30ms 전, mouse click event cb이 완료되고 Queue의 첫번째 timer cb이 실행된다. 
 . 30ms 시점에 interval cb을 실행하려 하지만 역시나 실행할 수 없는 상태라 Queue에 등록해야 하지만 브라우저에서 drop 시킨다. 
   > 긴 코드의 실행 시 발생되는 interval cb이 모두 Queue 등록되어 처리가 된다면 코드 완료 후 연속적인 interval 등록 코드들이 호출 되므로 브라우저에서 interval cb의 기등록 여부를 판단하여 drop 하는 것으로 보임.
 . 35ms 이후 timer cb이 완료 되고 Queue에 있던 interval cb이 실행된다.

- 40ms, interval cb이 실행되려 하지만 역시나 실행할 수 없는 상태라 Queue에 등록 (Queue : interval cb)
 . 40ms 이후 intervale cb이 완료되고 Queue에 남아 있던 interval cb이 실행된다. (Queue : nothing)


정리해보면
- JavaScript engine은 single thread 기반이라 비동기 event들을 queuing하여 실행한다. 
- setTimeout, setInterval은 비동기 코드를 실행하는 방법이 근본적?으로 다르다.
- timer cb의 실행이 block될 경우 다음 가능한 시점까지 delay된다.
- interval cb의 실행 시간이 delay보다 크다면 delay 없이 반복적으로 계속 실행 될 수 있다.


추가로 예제 코드를 보면

  1.   setTimeout(function(){
  2.     /* Some long block of code... */
  3.     setTimeout(arguments.callee, 10);
  4.   }, 10);
  5.   setInterval(function(){
  6.     /* Some long block of code... */
  7.   }, 10);

함수 정의 상으로는 두 코드 모드 10ms 간격으로 실행되는 것이 맞지만
setTimeout은 long code block이 실행된 뒤 10ms 이후에 실행 시도 하는 것이고
setInterval은 long code block을 이전 코드 실행완료 여부에 상관없이 10ms 간격으로 실행 시도 하는 것으로 차이가 있다는 것을 판단할 수 있을 것이다.


- 추가로 10ms 이하로 시간에 특정 코드를 호출하는 방법에 대한 포스팅

setTimeout with a shorter delay, David Baron
http://dbaron.org/log/20100309-faster-timeouts

2014년 11월 23일 일요일

답을 내는 조직, 방법이 없는 것이 아니라 생각이 없는 것이다


답을 내는 조직 : 방법이 없는 것이 아니라 생각이 없는 것이다
김성호 저 | 쌤앤파커스 (읽고 보니 쌤앤파커스
http://news.khan.co.kr/kh_news/khan_art_view.html?artid=201409172149355&code=940202 )

http://www.yes24.com/24/goods/7960047?scode=029



도서관에 있길래 빌려 봤음.
서점 순위에 스테디셀러로 올라와 있기도 했었고.. 일본전산 이야기의 저자 이기도 해서 이다.
사실 일본전산 이야기는 보진 못했다. 몇몇 사람들이 특이한 회사라고 말하며 이야기를 했었지만 그냥 좀 색다른 회사의 이야기로만 들렸었다.

암튼, 제목에서 보다시피 좀 과격한 문구("너가 생각이 없는거야" 라고 들리는)가 눈길을 끈다.
나이가 조금씩 들며 조직에서 뭔가 정체되어 가고 발전이 더뎌지는 잉여 취급이라 더욱 저 문구가 대여를 하게 만든 이유가 아닌가 생각 되기도 한다.


책에서는 내내 뛰어남 보다는 근성을 가지고 끝장을 보라는 얘기를 자주 한다. 조직 내에서도 4가지 분류의 특성을 가진 사람들이 존재 하는데 그 중에서 해결사형의 타입이 성공을 하게 된다는 이야기다.

"내가 분명히 지시했는데도 대충 해놓고 다 했다고 손 놓는 부하 직원이 있다. 일을 할수록 오히려 방해만 된다."
"시키지 않으면 꼼짝도 안 하는 삼류직원 때문에 골치 아프다."

예로 책에서 후지 필름 이야기가 나온다.
난 후지필름이 워낙 잘 나가는 것 처럼 보여 문제가 없었던 것 같았는데 책에서는 주력인 필름 산업이 급격히 축소되어 이를 해결하고자 구조조정, 비용 절감을 바탕으로 하여 끊임없는 노력을 통해 화장품과 의약품 쪽으로 신규산업을 확장해서 위기를 벗어났다는 이야기를 해준다. 그리고 책에서는 성공에 안주해 늦게 대응했던 코닥에 비해 악착같이 달려 들어서 발전하려는 몸부림이 후지필름에 있었다는 것을 강조하며 근성의 필요성을 말해 주었다.


책에서는 조직 구성원의 4가지 유형을 '평론가형', '무기력형', '막무가내형', '해결사형'을 언급하고 있다. 이 유형들을 보며 좀 반성한 것이 배우겠다는 의지가 없고 소통할 기회를 만들지 않고 무슨일에든지 겁부터 내고 자기 생각이 아니라 '안 된다'는 남들 이야기에 의존하는 것이 무기력형인데.. 꼭 나를 말하는 것 같았다.

또한 책 중반부에서 "진정한 답을 나올 때 까지 고민하고 남들과 싸워라"라고 하는데 실제 얼굴 붉히며 싸우라는 것이 아니라 남들과 논쟁을 해서 제대로 된 해법을 찾으라는 것을 강조하고 있다. 실제 나의 경우 책에서 말하는 bad case 직원인 '좋은 게 좋은 거지'라고 생각하며 싸움을 피하는 경향이 있는데 '제대로 논쟁을 즐길 줄 아는 직원'이 되고자 노력해야 겠다는 생각을 곰곰히 하게 되었다.


교육의 중요성을 말하며 두산그룹의 "사람이 성장하고 사업이 성장한다.", 조선시대 거상 임상옥의 "장사는 이문을 남기는 것이 아니라 사람을 남기는 것" 언급 하는데 진정으로 맞는 말인것 같다. 회사나 조직 입장에서 인력들의 성장을 위한 방법, 시간을 제공하는 것이 필수 인것 같다.


책 후반부에서 답을 찾는 5단계를 말하고 있다.
1. 일을 제대로 이해하기
2. 문제가 보이도록 자신을 두기
3. 답을 생각하는 시간 갖기
4. 답을 찾아 시행착오 건너기
5. 논쟁으로 답을 완성하기

각 단계에 동의 하며 그중 내가 생각하기에 가장 못하는 것은 5번인데 책에서는 나같이 "동료들끼리 목소리 높이느니 내가 조금 양보하겠다"며 논쟁에서 물러서는 사람을 '문제적 직원'으로 말하고 있다. 논쟁을 통해서 최고의 대안을 찾을 기회를 아예 차단해 버린다는 이유를 들고 있다.


조직에서 좀 정체된 상태에서 매사에 한걸음 물러나 방관자적인 시점에서 일을 하고 최선의 답을 찾기보다 쉽고 간단히 처리할수 있는 방법을 찾아하는 나에게는 도전을 주고 다시금 성장할 수 있도록 해주는 책같아서 개인적으로는 두고 보고 싶은 책이다.



2014년 10월 29일 수요일

Android 5.0 Lollipop 롤리팝 관련 이슈 사항들

구글러인 양찬석님께서 아래에서 잘 정리하였음.

개발자를 위한 안드로이드 5.0 롤리팝의 중요 변경사항 정리
: http://googledevkr.blogspot.kr/2014/10/android-50-api21-changes.html

위 내용과 중복될 수 있으나 오늘 GDG 모임에서 강조된 내용은


- 롤리팝 OTA 11월 3일 부터 Nexus 시리즈에 순차적으로 적용됨.

- 킷켓에서의 ART와 Lollipop의 ART는 차이가 있으므로 L preview 버전으로 테스트를 해봐 야 한다.
 : 특히나 게임, NDK, 보안 모듈 사용한 앱들은 대부분 이슈가 생길 수 있음.

- Custom permission 이슈
 : 여러 앱들에서 동일한 이름의 custom permission을 사용한다면 설치 순서상 뒷쪽 앱에서 선언된 permission으로 오버라이드가 된다.
 : 자세한 내용은 marojun님의 포스팅을 참고
https://medium.com/marojuns-android/android-5-0-%EB%A1%A4%EB%A6%AC%ED%8C%9D%EC%97%90%EC%84%9C%EC%9D%98-%EC%9D%B4%EC%8A%88-%EB%B0%8F-%ED%95%B4%EA%B2%B0-ffc85b8a68e3

- Service binding시 암시적 intent를 사용하면 exception이 발생되므로 명시적 intent를 사용하여 binding하라.


새롭게 출시되는 Nexus 6, Nexus 9에 대한 고려사항은 아래 링크를 참고

Getting Your Apps Ready for Nexus 6 and Nexus 9
: http://android-developers.blogspot.kr/2014/10/getting-your-apps-ready-for-nexus-6-and.html

 . Nexus 6  의 해상도 처리를 위해서는 XXXHDPI 해상도 사용
 . Nexus 9  의 화면비는 4:3 이므로 게임 같은 경우 해상도 고려 필요

2014년 10월 22일 수요일

폴리글랏 프로그래밍(POLYGLOT PROGRAMMING)

폴리글랏 프로그래밍 : 새로운 자바 언어를 기다리는 히치하이커를 위한 안내서
임백준 저 | 한빛미디어

http://www.yes24.com/24/Goods/12204890?Acode=101


처음엔 책의 부제 "새로운 자바 언어를 기다리는 히치하이커를 위한 안내서"에서 보다시피
자바 얘기만 나오는 책이라 전혀 자바 쟁이가 아닌 나에겐 별 의미 없는 책이라고 생각했었음.

하지만 저자가 임백준님이시고 기존 책들도 재미있게 봤던 지라 서점에서 읽다가 구매하게 되었고 그리고 스칼라에 대한 얘기도 나와서 무엇인지 궁금하기도 했었다.

읽다 보니 폴리글랏 프로그래밍(polyglot programming)의 개념과 시작점, 자바 언어의 역사, 이를 기반으로 한 새로운 언어들의 탄생, 언어별 비교 및 고찰, 앞으로 발전될 방향에 대해서 말하고 있어 한번에 쭉 읽어 버렸었다.
아마도 책이 읽기 쉬운 역사의 흐름이나 간략한 예시를 통한 언어 소개로 구성이 되어 있고 책의 챕터도 1. 자바, 2. C#, 3. 스칼라 딱 세개인것도 이유이지 않을까 생각한다.

읽다가 인상 깊었던 부분은 기존 언어들이 새로운 feature를 추가해가며 좀더 편한 언어 사용을 돕는 모습에서도 역시 언어라는 것은 언제나 변화해 가야 하는 것이고 개발 용이성? 측면도 무시 못할 것이구나 라는 점이었다.

또한 책을 읽으면서 공감이 되는게 프로그래머라면 기본으로 자료구조와 알고리즘의 이해를 바탕으로 여러 언어에 능숙해야 하겠다라는 생각과 또한 여러 언어를 배우고 사용하다보면 자연스럽게 개발하기 편한 언어를 바라보게 된다는 점이다.

실제 컴파일러 기반 언어를 주로 사용하여 실제 스크립트언어를 쉽게 봤다가 실제 개발 용이성과 퍼포먼스 측면에서 깜놀했던 적이 있어 지금은 생각을 많이 바꾸게 되었고 함께 되도록이면 스크립트 언어를 더 배우고 깊게 알고자 하고 있기도 하다.

.... 공부할 것은 언제나 산더미구나...

2014년 10월 21일 화요일

New native API in Tizen 2.3 Beta

Tizen 2.3 Beta 부터
기존 Native Framework layer에서 제공하던 OSP API(C++)들이 제거되고
Core layer의 C API들을 바로 사용하게 되었음. (하단 그림 참고)

https://www.mail-archive.com/general@lists.tizen.org/msg02334.html


기존 OSP API 쓰던 사람들은 멘붕일듯....

Tizen architecture

2014년 10월 20일 월요일

Android WebView

Android WebView 관련 궁금한 것들 찾아봄.


[General]

API Reference
: http://developer.android.com/reference/android/webkit/WebView.html

Tutorial with Android Studio
https://developer.chrome.com/multidevice/webview/gettingstarted

Building Web Apps in WebView
http://developer.android.com/guide/webapps/webview.html

Pixel-Perfect UI in the WebView
https://developer.chrome.com/multidevice/webview/pixelperfect

WebView를 이용한 App 개발 tutorial
 by 제트스윙(http://www.zetswing.com)

http://www.zetswing.com/bbs/board.php?bo_table=java_04&wr_id=2
  http://www.zetswing.com/bbs/board.php?bo_table=java_04&wr_id=3
    > Android 버전별 file chooser 동작 이슈 해결 방법 설명
  http://www.zetswing.com/bbs/board.php?bo_table=java_04&wr_id=5


[Chrome based WebView (Android 4.4.3 later)]

아래 링크에서 언급된 것 처럼 Android 4.4.3(KitKat)에서 부터 Chrome 기반 WebView가 사용되고 있다고 함.
 . Android 4.4.3에서는 Chrome 30.0.0.0 기반 WebView가 사용되고 있음.
 . Android L Developer Preview에서는 36.0.0.0 기반이 사용되고 있다고 함.
   : https://developer.chrome.com/multidevice/webview/overview
   : Android 5.0 LOLLIPOP에서는 37.0.0.0 기반이며 System WebView를 제공하여 Google Play Store를 통해 업데이트 되어 파편화 문제가 사라짐.
    > http://youtu.be/HHXwsgw7M8s?t=3m13s


WebView User Agent 
https://developer.chrome.com/multidevice/user-agent#webview_user_agent
Old WebView UA:Mozilla/5.0 (Linux; U; Android 4.1.1; en-gb; Build/KLP)AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30
New WebView UA:Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_)AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0Mobile Safari/537.36

Supporting Chrome(for Android)'s feature 
WebView v30WebView v33WebView v36
WebGLxx
WebRTCxx
WebAudioxx
Fullscreen APIxxx
Form validationx
Filesystem APIxxx
File input typexxx
<datalist>x
잘모르겠고 Android 5.0 LOLLIPOP의 WebView에서는 WebRTC가 된다는 말인가?
WebRTC의 자세한것은 => http://www.html5rocks.com/ko/tutorials/webrtc/basics/


Supporting hardware sensor APIs on new WebView
WebView v30WebView v33
Geolocation API
(requires
android.permission.ACCESS_COARSE_LOCATIONand/or
android.permission.ACCESS_FINE_LOCATIONpermissions)
Device Orientation APIxx
Media Capture and Streamsxx
Vibration API
(requires android.permission.VIBRATEpermission)
x
LOLLIPOP에서는 Vibration API가 지원된다는 얘기 이고 vibrations API는 아래 참고
=> https://developer.mozilla.org/ko/docs/Web/Guide/API/Vibration/Vibration


[Interface between JavaScript and Native]

아래 링크 참조
http://developer.android.com/guide/webapps/webview.html#UsingJavaScript

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
1. WebView를 생성
2. WebView의 WebSettings의 setJavaScriptEnalbed(true) 설정

public class WebAppInterface {
    Context mContext;

    /** Instantiate the interface and set the context */
    WebAppInterface(Context c) {
        mContext = c;
    }

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
}
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
3. JavaScript interface class 구현 및 설정

<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
    function showAndroidToast(toast) {
        Android.showToast(toast);
    }
</script>
4. Javascript에서 Native 호출


addJavascriptInterface를 좀 더 들여야 보면
http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)

- Interface class의 method들 중
 . JELLY_BEAN_MR1 이상 : public method들과 @JavascriptInterface 명시된 것들만 호출
 . JELLY_BEAN 이하 : 모든 public method들이 호출 된다.
 => WebView를 사용한 app이 의도치 않은 JELLY_BEAN 이하 버전에서 동작할 때 webview interface의 모든 methods들이 호출 될 수 있으므로 보안상 신중하게 interface를 구현할 필요가 있음.

- JavaScript는 WebView의 private, background thread와 연동되므로 thread safety를 염두 해야 한다고 한다.. 실제예는 안 찾았음.
- Android 5.0 LOLLIPOP API level의 application의 WebView에서는 injected된 Java object의 methods들이 JavaScript에서 확인 가능하다고 한다.. 안해봄..
- Interface class의 method들은 primitve를 사용하는게 기본이겠지만 어떤 사람들은 JSONObject, JSONArray도 사용 가능하다고 한다..  안되면 그냥 stringify해서 넘기면 될듯
 => http://stackoverflow.com/questions/2250917/passing-a-javascript-object-using-addjavascriptinterface-on-android
 Java object를 넘겼다는 사람도 있는데 봐도 이해가 안되고 왠지 그대로 하다가 고생할것 같다.. => http://stackoverflow.com/questions/21173888/how-to-pass-non-primitive-object-from-java-to-js-by-android-addjavascriptinterfa


[Android 버전별 WebView 이슈들]

Migrating to WebView in Android 4.4
: https://developer.android.com/guide/webapps/migrating.html

kitkat(4.4)에서 맞닥뜨린 이슈 및 해결
by marojun
https://medium.com/marojuns-android/kitkat-4-4-%EC%97%90%EC%84%9C-%EB%A7%9E%EB%8B%A5%EB%9C%A8%EB%A6%B0-%EC%9D%B4%EC%8A%88-%EB%B0%8F-%ED%95%B4%EA%B2%B0-1ecb94c24694

버전별 WebKit 버전
by Padgom
: http://padgom.tistory.com/entry/Android-%EB%B2%84%EC%A0%84%EB%B3%84-Webkit-%EB%B2%84%EC%A0%84

@JavascriptInterface
Caution: If you've set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotationto any method that you want available to your JavaScript (the method must also be public). If you do not provide the annotation, the method is not accessible by your web page when running on Android 4.2 or higher.



[Remote Debugging on Android with Chrome]
: https://developer.chrome.com/devtools/docs/remote-debugging


[기타]

찾다 보니 Mozilla GeckoView도 있구나..

HTML5의 충실한 지원으로, Android WebView를 대체하는 View로 충분한 Mozilla GeckoView 사용하기.. by 코딩한줄에 12시간
: http://sjava.net/?p=471


WebView attack 관련 논문
선 링크 후 분석...
http://www.cis.syr.edu/~wedu/Research/paper/webview_acsac2011.pdf





2014년 10월 15일 수요일

[links] Growth Hacking, 그로스 해킹

Growth Hacking 용어가 여기저기서 사용되기에 한번 찾아 본 link들 모음.

7월에 있었던 벤 레비의 강연 영상과 요약 기사

스타트업, 앞 길이 막막하다면 그로스해킹을 하라! – 벤 레비(Ben Levy) 강연
posted by 정 새롬 
: http://besuccess.com/2014/07/ben-levy/

그로스해킹(Growth Hacking)이란?
2010년 션 엘리스(Sean Ellis)의 ‘Find your growth hacker for your startup’이라는 블로그에서 처음 사용된 용어로 제품 또는 서비스의 중요한 지표를 지속적으로 파악하고 분석하여 사용자의 흐름을 최적화하는 동시에 많은 유저를 확보하는 전략적 마케팅 기법을 뜻한다.

...

(TODO) 아래 tool들은 한번 찾아 봐야 겠음.

그외 기본적인 개념이 정리되어 있으니 위 링크를 참조해서 보는게 좋겠음.

[PT] Growth Hacking by Mattan Griffel , Founder and CEO at One Month
: http://www.slideshare.net/mattangriffel/growth-hacking
Social Media Week에서 발표된 자료 같은데 여러 기업의 예를 보여주고 있어 다소 분량이 많고 자세하다.
PT 말미에 growhack.com에서 Growth Hacking case studies 문서(WSJ, Twitter, Living Social)를 제공하고 있는데 그렇게 영양가가 있는 자료는 아니지만 이메일만 등록하면 받을 수 있음.


'Growth Hacking(그로스 해킹)'이란?, 적용 사례 by Pristones
http://sudo.pristones.com/2014/03/31/growth-hacking-1/
첫번째 링크는 개념을 간략히 정리한 것이고 두번째 PT는 실제 사례를 포함하여 설명하고 있음.



관련 서적
: http://www.amazon.com/Growth-Hacker-Marketing-Primer-Advertising-ebook/dp/B00EWPMUKM/ref=tmm_kin_swatch_0?_encoding=UTF8&sr=1-1&qid=1413268841

예전에 국내 앱 개발사의 사례가 있었는데.. 못찾겠네..

2014년 10월 13일 월요일

html5 canvas를 blob data로 변환하여 POST upload하는 방법

mobile web상에서 display하는 image를 업로드 하는 방법을 찾아봄.

일반적으로는 form data를 이용하여 선택된 image 파일을 업로드 하지만
form data 없이 load된 image나 Canvas를 업로드 하는 방법을 찾고자 하였음.

참고로 전송하려는 image(canvas내 image라도)가 다른 site에서 loading 된 것이라면
JavaScript의 동일 도메인 참조정책으로 인해 아래 방법을 사용할 수 없다.
 : http://stackoverflow.com/questions/2390232/why-does-canvas-todataurl-throw-a-security-exception
up vote51down voteaccepted
In the specs it says:
Whenever the toDataURL() method of a canvas element whose origin-clean flag is set to false is called, the method must raise a SECURITY_ERR exception.
If the image is coming from another server I don't think you can use toDataURL()
share|improve this answer
Same-Origin Policy(동일 도메인 정책)
http://charlie0301.blogspot.kr/2013/12/jquery-ajax-same-origin-policy-jsonp.html

-----------------------------------------------------------------

Canvas를 image/jpeg 형식의 blog data로 변환한 뒤 XMLHttpRequest를 사용하여 POST upload 하는 방법
http://stackoverflow.com/questions/18253378/javascript-blob-upload-with-formdata


function uploadCanvasData()
{
    var canvas = $('#ImageDisplay').get(0);
    var dataUrl = canvas.toDataURL("image/jpeg");
    var blob = dataURItoBlob(dataUrl);
    var formData = new FormData();
    formData.append("file", blob);

    var request = new XMLHttpRequest();
    request.onload = completeRequest;

    request.open("POST", "IdentifyFood");
    request.send(formData);
}

function dataURItoBlob(dataURI)
{
    var byteString = atob(dataURI.split(',')[1]);
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++)
    {
        ia[i] = byteString.charCodeAt(i);
    }

    var bb = new Blob([ab], { "type": mimeString });
    return bb;
}
answered Aug 15 '13 at 22:54
Max Ehrlich
639420




먼저 Canvas.toDataURL()을 통해서 DataURI를 뽑아낸다.

Syntax

canvas.toDataURL(type, encoderOptions);
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement.toDataURL

toDataURL() method는 사용자가 지정한 encoderOptions(default는 PNG)의 MIME을 가지는 96dpi resolution의 image dataURI를 제공한다.
(canvas의 height, width중 하나라도 0이면 "data:,"를 리턴한다고 함.)

제공되는 DataURI의 형식은 다음과 같다.

Syntax

The data URIs have the following syntax:
data:[<mediatype>][;base64],<data>
https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

RFC 2397에 따라 해당 data를 document에 첨부할 수 있도록 위의 syntax로 표현하는 것이고 base64 encoding 방법이라던지 사용되는 protocol은 위키피디아를 참고하면 될듯

그래서 제공된 DataURI를 가지고 dataURItoBlob()함수를 사용하여 실제 data부분(<data>)을 뽑아내고 blob data로 변환한뒤 formdata에 삽입하여 POST uploading을 하게 된다.


Canvas.toDataURL() 사용예
http://m.mkexdev.net/106
http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-url/

MDN에서 binary data를 보내는 방법에 대해서 설명한 포스팅
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data


dataURI를 blob으로 바꾸는 함수의 다른 버전이다.
: http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata