일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Spring
- 알고리즘
- BOJ
- spa 라우팅
- 텐서플로우
- 타입변수
- 백준
- 인공지능
- 리스트
- 검색어최적화
- 드래그방지
- 리스트구현
- Java
- 리눅스
- SWEA
- 서버사이드랜더링
- 연결리스트구현
- let과var차이
- 파이썬
- 주피터
- BOJ17070
- SPA
- BFS
- 고쳐야해!
- 스프링
- 파이프 옮기기
- 머신러닝
- 딥러닝
- jnut
- 타입제한
- Today
- Total
林's
[Front] 불펌방지 적용하는 방법 본문
요즘은, pc보다 모바일을 더 많이 사용하는 시대죠.
사진이나 동영상의 경우 스마트폰을 길게 누르면 나타나는 contextmenu 창을 통해 손 쉽게 이미지나 영상을 다운로드 할 수 있습니다.
저작권이 있는 이미지라면, 이는 상당히 골치아픈 문제가 될 수 있습니다.
사용자와 창작자 둘을 보호하기 위한 취지로 개발된 소스이나, 요즘 스마트폰은 해상도도 좋아서, 스크린샷을 찍어버리면 사실 답이 없습니다.. ㅎㅎ
그래도 개발해야한다면 어쩔 수 없겠죠.. 안드로이드와 PC, 그리고 IOS 계열의 경우 크로스 브라우징을 생각한 적용법을 알아봅시다.
1. 과거에는 어떻게 했을까?
단순히, contextmenu 이벤트를 캐치해서 기본동작을 막아버리는 방법을 사용했습니다.
1). PC/Android
class ImageProtector {
protect = (img) => {
img.addEventListener('contextmenu', this.onContextMenu);
};
unprotect = (img) => {
img.removeEventListener('contextmenu', this.onContextMenu);
};
onContextMenu = (e) => {
e.preventDefault();
e.stopPropagation();
// alert("저작권 보호를 위해서 복사는 금지되어 있습니다.");
};
}
export default new ImageProtector();
2). IOS/IPhone
ios는 간단합니다. 아래의 css를 img 엘리먼트에 추가해주면 됩니다.
.hide_context_menu {
-webkit-touch-callout: none;
}
요로케 말이죠~
<img className="hide_context_menu"/>
하지만, 이 css는 ios11 이하에서는 동작하지 않습니다.
2. 크로스 브라우징
오래된 IOS 버전에서는 위의 css 가 적용되지 않고, Android WebView 에서도 contextmenu 가 동작하지 않는 경우가 있습니다.
이럴 경우에는, contextmenu 가 뜨기 직전에 alert() 함수를 호출시켜서 컨텍스트 메뉴가 뜨는 걸 막는 방법이 있습니다.
alert와 confirm 함수에는 이전 프로세스를 일시 정지 시키는 기능이 내장되어 있기 때문인데요.
이러한 특징을 활용하여, 메뉴창이 뜨기 바로 직전에 호출시켜서 막아버리는 방법을 사용해보죠!
const DURATION_TOUCH = 420;
class ImageProtector {
static timer = null;
protect = (img) => {
img.addEventListener("touchstart", this.onTouch, false);
img.addEventListener("touchmove", this.stopTimer, false);
img.addEventListener("touchend", this.stopTimer, false);
}
unProtect = (img) => {
img.removeEventListener("touchstart", this.onTouch);
img.removeEventListener("touchmove", this.stopTimer);
img.removeEventListener("touchend", this.stopTimer);
}
onTouch = () => {
this.stopTimer(); // 확대 축소와 관련된 이벤트를 쓰고 있을 경우 타이머를 꺼줘야합니다.
ImageProtector.timer = setTimeout(() => {
alert("저작권 보호를 위해 이미지를 저장할 수 없습니다.");
this.stopTimer(); // alert 이후에 사진선택 상태일 시, touchend 가 호출되지 않습니다. 그래서 여기서 제거해요.
}, DURATION_TOUCH);
}
stopTimer = () => {
ImageProtector.timer && (ImageProtector.timer = clearTimeout(ImageProtector.timer));
}
}
export default new ImageProtector();
사용하실 때는 import ImageProtector from "소스 경로";
처럼 편한 이름으로 임포트를 하시고, 이미지 레퍼런스를 함수에 전달해서 쓰시면 됩니다. : )
ImageProtector.protect(이미지레퍼런스);
ImageProtector.unprotect(이미지레퍼런스);
저와같은 문제를 겪으셨던 분들에게 많은 도움이 되길 기도합니다. ^^
'프로그래밍 > 웹프론트' 카테고리의 다른 글
[SPA] 서버사이드 랜더링과 SPA 라우팅의 동작원리 (0) | 2019.09.20 |
---|---|
[ES6+] const, let, var (0) | 2019.09.13 |
[React] vscode script 안에서 emmet 사용하는 방법 (0) | 2019.09.01 |
[WEB Front] veter 와 eslint 충돌 해결법 (0) | 2019.07.27 |