Clipboard API 사용하기

가누·2023년 1월 22일
1

개요

기존에 웨이브온에서 엘리먼트의 복사/붙여넣기는 같은 탭 내에서만 가능했다. 그 이유는 기존에는 클립보드가 아닌 상태 관리 라이브러리인 Vuex를 활용해 복사가 된 엘리먼트의 정보를 관리 했기 때문이다. 이렇게 하면, 사용자로부터 클립보드 접근 권한을 받지 않아도 되기 때문에, 사용자도 좋고(?) 개발하는 나도 편하다. 다만, 이 방법의 치명적인 문제점은 Vuex에 저장 된 데이터는 브라우저 탭 간 공유가 되지 않는다. (별도의 라이브러리 사용하지 않는 한...)

Clipboard API 사용하기

따라서 여러 개의 탭에서 앱을 열어 작업을 할 때, 앱 간 복사가 되지 않아 불편하다는 피드백을 여러번 받았다. 이를 해결하기 위해 Clipboard API를 사용하기로 했다. (Document.execCommand() 방법도 있지만 mdn 공식문서에 따르면 deprecated 되어 권장하지 않는다고 한다.) 사용법은 아주 간단하다.

참고로, Clipboard API는 https 또는 localhost 환경에서만 동작한다.

우선, 복사하는 법 즉, 클립보드에 write 하는 방법부터 알아보자. 클립보드에 write 하는 방법으로는 write 메소드와 writeText 메소드가 있는데, 나는 writeText 를 사용하였다. 참고로, 클립보드에 write 할때는 대부분의 경우 별도의 권한을 필요로 하지 않는다. (탭이 활성화만 되면 자동으로 권한이 주어진다.)

navigator.clipboard.writeText("복사된 텍스트").then(
  () => {
    // 클립보드에 write이 성공했을 때 불리는 핸들러
  }
);

writeText 메소드는 비동기 함수로 Promise를 리턴한다. 따라서, 위와 같이 클립보드에 성공적으로 write 되었을 때 수행할 작업을 then 메소드의 인자로 넘겨준다. 물론 위의 코드는 async/awaittry/catch 문을 이용해 다음과 같이 표현해 주어도 된다.

async function copy(){
  
  try{
    await navigator.clipboard.writeText("복사된 텍스트");
    
    // 클립보드에 write이 성공했을 때
    success();
  }catch{
    
    // 클립보드에 write이 실패했을 때
    fail();
  } 
  
}

이번에는 클립보드에 있는 내용을 가져와 붙여넣기 하는 방법, 즉 클립보드를 read 하는 방법에 대해 알아보자. read는 사실 클립보드를 write 할 때와 굉장히 유사한데, 하나의 큰 차이점은 read는 유저의 권한을 필요로 한다는 것이다. 왜 굳이 별도의 권한을 필요로 할까라는 궁금증이 들 수도 있지만, 사실 조금만 생각해보면 충분히 이해가 되는 부분이다. 클립보드에 민감한 정보가 저장되어 있다면, 당연히 함부로 읽을 수 없게 막아야할 것 아닌가!

마찬가지로 readreadText 하는 있는데, 여기에선 readText 만 다루도록 하겠다. 사용방법은 writeText 와 거의 유사하다.

navigator.clipboard
  .readText()
  .then((clipText) => {
  
  // 붙여넣기에 성공하면 불리는 함수
  Foo()
});

만약, readText 에 성공하면, 클립보드에서 읽은 텍스트를 반환하게 된다. 물론 위의 코드는 async/awaittry/catch 문을 이용해 다음과 같이 표현해 주어도 된다.

async function paste(){
  
  try{
    const clipText =  await navigator.clipboard.readText();
    
    // 클립보드 read에 성공했을 때
    success();
  }catch{
    
    // 클립보드 read에 실패했을 때
    fail();
  } 
  
}

객체를 클립보드에 저장하기

한 가지 추가적인 팁이라면, readTextwriteText 는 메소드의 이름에서 알 수 있듯 string 타입을 다룰 때만 사용할 수 있다. 만약 그럼, object 타입을 복사/붙여넣기 하고 싶을때는 어떻게 처리해야할까? JSON.stringify()JSON.parse() 를 사용하면 된다.

const obj = {name: "hello"};

// obj -> text로 변환
const text = JSON.stringify(obj);

// 복사하기
navigator.clipboard.writeText(text);

// 붙여넣기
navigator.clipboard
  .readText()
  .then((clipText) => {
  
  // string에서 object로 변환
  JSON.parse(clipText);
});

즉, 위와 같이 복사할 때는 JSON.stringify() 를 사용해 객체를 문자열로 변환하고, 붙여넣기 할때는 JSON.parse() 를 사용해 문자열을 객체로 변환하면 된다.

이렇게 클립보드를 사용하면, 앱간 복사도 잘 되는 것을 볼 수 있다. 다만, 클립보드를 이용하여 복사/붙여넣기를 구현하면, 어쩔 수 없이 클립보드 읽기 권한을 따로 요청해야하는데 이는 사용자 경험에 좋을 리가 없다. (브라우저에 팝업이 뜨는게 사용자 입장에서 썩 명쾌하지 않을 수 있다.)

그런데, Canva나 wix 등에서 복사/붙여넣기를 해보면 클립보드 접근 권한을 요청하지 않는다. 그럼 이들은 대체 어떻게 한 것일까 연구해보았다. 정답은 아예 클립보드를 사용하지 않는다 이다.

위에 보이는 것처럼 복사, 붙여넣기 할때마다 api를 요청하는 것을 알 수 있다. 즉, 이들은 서버를 마치 클립보드처럼 활용하는 것이다. 우리도 언젠가는 이렇게 해야하지 않을까?

profile
가누입니다.

0개의 댓글