글쓰기 메뉴

[3분 복붙] 기사면 랜딩 PV 2배로 올리기.
브라우저 뒤로가기 제어.
이딴거 만들지 말자.

대부분의 서비스가 보다 많은 활동 사용자를 목표로 함은 분명하다.

하지만 얼마나 많은 활동 사용자가 있는지를 가늠할 수 있는 지표에 대한 목표설정은 좀 다른 얘기라고 생각한다.

심지어 그 목표의 달성을 위한 실현 과정이 사용자들을 열받게 만든다면 이 얼마나 근시안적 추태인지...


PV (Page View, 페이지 조회수) 에 대해 강한 집착을 보이는 국내 언론사들이 근래 "뒤로가기"가 실행되는 경우 이전 페이지로 보내지 않고 메인페이지로 이동되도록 하는 기능을 속속 도입하고 있더라. (좀 됐지.. 내가 잠수였던거지..)


사용자 입장에선 개빡치는 UX. 


그렇지만 남들이 한다니까 자기들도 해달라는 클라이언트의 등장은 당연지사.


해당 기능을 도입한 사이트들을 둘러보니 대부분 광고대행사 등이 제공한 스크립트를 사용하는 것 같더라.

메인페이지를 거치는 것도 짜증나는데 그 중간에 광고까지 껴있으니 개짜증..

이딴거 누가 안만들면 좋겠는데 일개 개발자가 뭘 할 수 있겠냐 고민하다가...


클라이언트에게 만들어준 간단한 스크립트를 모두에게 제공하고 너도나도 다들 도입해서 더 많은 사용자들이 더 빠르게 빡돌게 만들면 슬슬 이딴 쓰레기 같은 기능을 버리지 않을까라는 골때리는 결론에 도달했다.


0.

jQuery 를 사용하고 있다고 가정한다.


1.

아래의 코드를 기사 페이지 등 기능이 동작될 페이지에서 로드되는 js 파일에 추가한다.

3번 라인 정규식 패턴안의 synd\.kr 부분은 자신의 도메인으로 변경한다.

 

function initBackToMain() {
  var ref = String(document.referrer);
  if(!/synd\.kr/i.test(ref) || /(google|goo|facebook|fb)\.c/.test(ref)) {
    if(history && history.pushState) {     
      try {
        history.pushState({}, ''); 
        history.replaceState({}, '', "#direct")
        
        $(window).on("hashchange", function() { location.replace("/"); });
      } catch(e) {
        //
      }
    }
  }
};


2.

기능이 동작될 페이지 HTML 코드 사이에 아래의 코드를 삽입한다.

<script>
  $(function() {
    initBackToMain();
  })
</script>


완성!


코드는 단순해서 쉽게 이해할 수 있겠지만 몇몇 부분을 설명해보자면...


1. pushState 이후에 replaceState 를 다시 콜하는 이유.

pushState 만으로 history 를 조작할 경우 firefox 에서 백버튼이 골때리게 반복된다.

external > page > main > page > main > external

replaceState 를 다시 콜하면 아래와 같이 의도한대로 동작된다.

external > page > main > external


2. popState 이벤트를 사용하지 않고 hashChange 를 사용하는 이유

페이스북 앱 등 in app browser 를 사용할 때 해쉬가 없는 경우 뒤로가기 실행시 popState 이벤트가 발생되지 않음

해쉬를 추가해야 뒤로가기 실행 시 기존 URL (해쉬없는) 로 페이지 변화없는 이동이 발생하고 이 타이밍에 hashChange 가 콜 됨.

또한, Safari 9버전 이하에서 popState 가 지멋대로 fire 됨.


3. 이건 좀 쓸데없는 설명이지만 location.href 는 history 에 기록되고 location.replace 는 history 에 남지 않기 때문에 replace 를 사용해야함.


지원브라우저

웹이고 모바일이고 html5 history api 를 지원하는 브라우저 (http://caniuse.com/#search=history) 에선 기본적으로 모두 동작된다고 기대할 수 있으나 아이폰 크롬에서 동작안됨.

그 외 페이스북 앱 등 인앱에서 웹뷰를 사용하는 경우도 정상 동작.


Tested.

Microsoft Edge.

Microsoft IE 11.

Firefox 52.x (Windows)

Firefox 47.x (Linux)

Firefox 52.x (Mac)

Firefox 52.x (Android)

Firefox 6.x (iOS)

Chrome 57.x (Windows)

Chrome 48.x (Linux)

Chrome 56.x (Mac)

Chrome 57.x (Android)

Chrome 57.x (iOS) *동작안됨

Safari 10.x (Mac)

Safari 10.x (iOS)

Android 6 browser 4.x

Facebook App


자 이제 자리에서 일어나서 팀장이든 부장이든 상사에게 "저희 PV 를 2배로 올리겠습니다!" 라고 보고하고 보다 많은 사용자들의 빡을 돌려(?) 주삼. 

어디서 왔지?
다른 글들
2 2
Square 2f561b02a49376e3679acd5975e3790abdff09ecbadfa1e1858c7ba26e3ffcef

About을 만들어주세요

어바웃  페이지가 있으면 좋겠어요.  
어떤  아이디어로  시작하셨는지..  어떤 방향으로  움직이고  있는지. 궁금해지네요.
Trix인가요? 잘 동작하네요.

사진 첨부도 잘되구요~.
1 0

리디렉션 페이지에 구글 아날리틱스 코드 집어넣기

리디렉션 되는 페이지에 구글 웹로그 분석기 추적 코드를 넣고 meta 태그나 스크립트로 페이지를 이동시키면 데이터 수집이 완료되지 않은 상태로 페이지가 종료되고 로그가 남지 않는 문제가 있지.
리디렉션을 5초 정도로 잡아도 무관하다면 그냥 5초로 잡고 돌려도 OK.
리디렉션 타깃 페이지가 같은 도메인 아래에 있다면 타깃 페이지에 추적 코드가 있는 것 만으로 레퍼러로 처리되어 데이터가 수집되니까 이것도 OK.
하지만 리디렉션을 외부 사이트로 보내야하고 1~5초 정도 사용자를 묶어두는게 부담스럽다면 추적 코드의 동작이 완료된 후 리디렉션을 실행하면 되겠지.
2013년부터 사용된 Google Universal Analytics 추적 코드라면 hitCallback 콜백을 사용하면 되고 혹시 2013년 이전 코드라면 글로벌 오브젝트인 _gaq 큐에 함수를 밀어넣으면 된다네.
추적 코드 어딘가에 _gaq 가 있으면 그냥 오래된 코드, _gaq 가 없고 다음과 같이 추적코드가 시작된다면 Universal.
오래된 버전에서는 아래처럼 리디렉션이 가능
Universal 버전에서는 아래처럼 hitCallback을 사용할 수 있음
이상 끝!
1 3

페이스북 임베드 URL,
소셜 플러그인 (XFBML) 파싱

임베드 대상 페이스북 콘텐츠는 "포스트", "비디오", "사진" 이렇게 종류별로, 웹과 모바일에서 각각 URL 형식이 조금씩 달라 프로그램으로 이를 처리하기 위해 동일한 형태의 주소가 필요하다.
SDK를 사용해 페북 컨텐츠를 임베드하는 경우 기준이 되는 URL 은 웹용 URL 이다.
뭐, URL은 딱보면 알겠지만 fbid 라는 고유ID만 빼오면 된다. 
모바일에서 포스트에 대한 주소만 URL 파라미터로 처리되어 있고 나머지는 전부 URL Path에 포함되어 있으니 아래와 같은 정규식으로 fbid부터 발라내자
정규식은 Ruby 2.x 버전에서만 동작을 확인했지만 look-behind 와 look-ahead 외에 정규식 엔진을 타는 내용이 없기 때문에 동작이 안된다면 그 부분만 수정하자.
사실 효율을 생각한다면 저딴 정규식으로 한방에 fbid 를 뽑는 것 보다 fbid 가 파라미터로 존재하는 케이스를 분리시키고 나머지 정규식도 2회로 나눠 돌리는게 더 좋지만... 귀찮으니 한 줄로 하자.
상식적으로 fbid 만 뽑아내면 될 것 같으나 페북 임베드에 사용되는 URL은 사용자 아이디가 버킷 이름처럼 포함되어 있다. 문제는 모바일 URL에 사용자 아이디-문자-가 없다는 점.
이 문제는 페이스북의 짧은 주소 fb.com 을 사용해 해결할 수 있다. http://fb.com/<fbid>의 형식으로 리퀘스트를 보내면 해당하는 완성된 주소로 리디렉션 시켜준다. - 임베드 코드 생성 시 fb.com 을 그냥 쓸 수 있으면 좋을텐데 안되더라.
curl 로 리디렉션된 최종 URL을 뽑는 코드는 아래와 같다.
내가 쓰는 Typhoeus 에선 아래처럼 최종 URL을 받으면 된다. 
이렇게 얻은 URL 로 
위와 같은 XFBML을 사용해 임베드가 가능하다. 다양한 옵션은 페북 문서 확인.
Javascript SDK 를 사용하는 경우 SDK 가 로드된 후 FB 객체를 initialize 하면서 페이지에 있는 모든 XFBML 을 파싱할 수 있고, 이와 다른 타이밍에 추가적으로 XFBML 을 파싱해야하는 경우는 아래의 코드로 가능하다.
특정 엘레먼트만 파싱하려면
jQuery 로 돔을 잡아 파싱하려면
이렇게 파싱하면 컨텐츠가 임베드된다.
1 0

우분투 몽고DB 설치 및 부팅 시 자동 실행 - Install MongoDB on Ubuntu & Start MongoDB on system start

설치는 매우 간단하고 MongoDB 공홈에 최신 버전으로 갱신된 문서가 있어 해당 페이지를 참고하면 된다.
공홈 설치 문서 링크:

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/
GPG Key
리스트파일 생성 (16.04. 기타 버전은 공홈 참조)

패키지 디비 갱신
MongoDB 설치

근래의 대부분의 배포본은 Upstart  대신 Systemd를 사용하기 때문에 위와 같이 설치된 MongoDB 역시 init 스크립트를 제공하지 않는다.
service 커맨드로 시작, 중지, 재시작 등의 관리가 가능하나 systemctl 커맨드를 익히는게 바람직하다고 본다.
systemd 를 사용해 MongoDB 를 초기 실행 시키기 위해 다음의 파일을 작성한다.
/etc/systemd/system/mongodb.service

Unit 섹션의 Description 은 서비스에 대한 간단한 설명을 포함한다.
같은 섹션의 After 는 네트워크 연결 후 구동하겠다는 의미
Service 섹션의 User 는 서비스 실행 사용자를 지정하고 ExecStart 는 실제 구동 커맨드를 입력한다.
Install 섹션의 WantedBy 는 실행 타깃을 구분하는데 multi-user.target 은 기존 런레벨 2,3,4 로 일반적인 부팅 시에 동작된다.
구동
상태 확인
정지
부팅 시 실행
systemd 의 target 에 대해 보다 자세히 알고 싶다면 아래의 링크를 참조.
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Targets.html
systemd 에 대해 보다 자세히 알고 싶다면 아래의 링크를 참조
http://lunatine.net/about-systemd/
0 1
Square 2f561b02a49376e3679acd5975e3790abdff09ecbadfa1e1858c7ba26e3ffcef

라즈베리파이에서 5v 릴레이 사용하기

라즈베리파이랑 다른 전압 회로 연결을 위해 릴레이를 달았는데 GPIO에서 나오는 3.3V로 릴레이가 동작이 안돼. 원래 5V 릴레이기도 하지만 전류가 충분하면 3.3V에서 동작되는데 RPi GPIO 에서 나오는 전류가 50mA 근처라 Fail. 파나소닉꺼 3V 릴레이도 어렵게 구해봤는데 전류가 부족해서 Fail Again.
그래서 GPIO 에 5V 핀을 써서 릴레이를 동작시키는 회로.
트랜지스터랑 다이오드 하나씩에 릴레이만 있으면 되는데 나같은 전기.전자맹은 반도체 모델명이 딱 적혀있지 않으면 엄청 난감하거든. 세운상가가서 물어보고 구입한 부품은 트랜지스터: 2N3904, 다이오드: 1N4004 이렇게 샀어. 해봤더니 잘 됨 ㅇㅇ;
1 1

스팸블럭과 손님글 링크 제거, 아이폰 복붙 여전히 FAIL....

어흠흠. 로그인 필요없고 폼이 덜렁 나와있으니 당연하게도 스팸이 들어오기 시작했네.
온라인 스팸 특성상 도메인을 반드시 입력해야하니 스팸도메인을 등록시켜놓고 글이 등록되지 않게 막아놓긴했지만, 링크 클릭했다가 막 PC 감염되고 이러면 큰일나니까 게스트로 등록된 글에는 링크가 동작되지 않게 막아놨음.
아이폰에서 사파리고 크롬이고 복붙이 여전히 안디어 ㅠ.ㅠ
이거이 정말 에디터 문제인지 iOS 와 연관된 문제인지부터 다시 짚어봐야할 듯.
아이폰 사용자분들께 매우 죄송! 난 안드로이드지렁~ 
1 0

수줍게 물든 참꽃이
노랗게 피어난 개나리가
흩날리는 민들레가


봄이 왔다고
세상에 봄이 왔다고 세상을 물들이기 시작했다
나풀나풀 흰나비가
오밀조밀 토끼가
지저귀는 새들이


봄이 왔다고
세상이 봄이 왔다고 세상을 노래하기 시작했다
0 0

기분 안좋으면

글쓰고 싶은듯...
공격적인 말투..
니네가 좀 잘하지.. 니네팀 진짜 문제 많어...
왜케 퇴사하는것같니... 팀원 3명 남은게 정상이냐.. 몇명이었는데.. 으이그..
정신차려 남얘기 옮기지 말고
0 0

안녕, 레이나.

친애하는 레이나.
가끔은 비가 와도 우산없이 뛰쳐나가고 싶어하는 날이있어. 그건 나에게 충동에 불과했지만 너에게는 현실가능한 것이였지. 차갑게 내리는 비에도 너는 우산도 없이 맨발로 뛰쳐 나갔어.
그래 너의 발끝이 붉게 물들었다가 이내 하얗게 되는 것, 밝은 갈색의 머리카락이 비에 젖어들며 검게 변하는 것, 하얀 원피스가 곧 너의 살결을 내비치도록 젖어가는 것.
그것들 중에서 나는 어느 하나 놓치지 않았어.
사랑하는 레이나.
너의 웃음소리가 빗속에 잦아드며 골목을 울릴때, 그때 내 마음을 너의 비가 톡톡 두드렸단다. 너는 멍하니 서있는 나를 향해 뛰어오며 젖은 머리를 귀뒤로 넘겼지. 그리고 입김을 뿜는 붉은 입술로 속삭였어.
나만의 레이나.
너의 붉은 입술에 따라 나도 우산 없이 너만의 골목에 접어들었고, 너는 나에게 잊을 수 없는 비오는 날을 안겨줬어.
나만의 레이나, 나만의 레이나.
비가 이세상을 잠식하고 홍수로 만들어 버릴지언정, 그 어느 한방울의 비도 미워하지 않으리, 사랑하며 기꺼이 온몸으로 세차게 맞으리.