브라우저에서 JavaScript를 사용하여 클립보드를 데이터를 쓰거나 읽으려면 ClipboardAPI 또는 execCommand API 를 사용해야 합니다. 일반적으로 웹에서 클립 보드에 텍스트를 복사하는 실질적인 방법은 execCommand 를 사용하는 것이었지만, 이제는 ClipboardAPI 를 이용하여 좀 더 단순하고 쉽게 사용을 할 수 있습니다.

ClipboardAPI


ClipboardAPI는 Promise 기반으로 클립 보드 내용을 비동기식으로 접근할 수 있는 새로운 API입니다. 하지만 비교적 최신 스펙으로 아직 지원되지 않는 브라우저가 많습니다.

Chrome 66 이상에서는 '텍스트 복사 / 붙여넣기' 만 지원하지만, Chrome 76 이상에서는 'read(), write()'메서드가 추가되어 이미지와 같은 임의의 데이터를 읽거나 쓸 수가 있습니다.



아래와 같이 간단하게 내가 원하는 시점에 텍스트 데이터를 읽거나 쓸 수 있습니다.
단, 권한이 있어야 하고 브라우저가 활성화되어 있는 상태일 때만 사용할 수 있습니다.


// 읽기
navigator.clipboard.readText().then((text) => {
    console.log('Pasted content: ', text);
});

// 쓰기 
navigator.clipboard.writeText(location.href).then(() => {
    console.log('success');
});



drawing

그리고 'Permissions API' 를 활용하여 권한 상태를 확인할 수 있습니다.


// { name: 'clipboard-read' } 읽기 권한
// { name: 'clipboard-write' } 쓰기 권한 (브라우저가 활성화되어 있으면 자동으로 권한 부여)
navigator.permissions.query({ name: 'clipboard-read' }).then((permission) => {
    // 권한을 허용했을 때는 'granted'
    // 권한을 거절했을 때는 'denied'
    // 권한을 요청 중일 때는 'prompt'
    console.log(permission.state);

    // 권한 상태가 변경 됬을 때마다 이벤트 발생
    permission.onchange = () => {
        console.log(permission.state);
    };
});



Chrome 76 이상에서의 'blob''text()''arrayBuffer()'가 추가되어 좀 더 간편하게 데이터를 다룰 수 있습니다.


const $clipboard = document.getElementById('clipboard-btn');
$clipboard.addEventListener('click', async () => {
    const clipboardItems = await navigator.clipboard.read();
    
    for (const clipboardItem of clipboardItems) {
        for (const type of clipboardItem.types) {
            const blob = await clipboardItem.getType(type);
            
            // text
            if (type === "text/plain") {
                const text = await blob.text();
                console.log(text);
            }

            // binary data
            if (type === "image/png") {
                const imageData = await blob.arrayBuffer();
                console.log(imageData);

                /*
                const reader = new FileReader();
                reader.addEventListener('loadend', (data) => {
                    const imageData = data;
                });
                */
            }
        }
    }
});





execCommand API


'navigator.clipboard.writeText()'를 이용하여 권한 없이 클립보드 데이터를 저장할 수 있지만, 지원 브라우저 스펙이 높기 때문에 exeCommand() 메소드를 이용하여 아래와 같이 사용할 수 있습니다.


function copyClipboard(value) {
    const $text = document.createElement('textarea');
    document.body.appendChild($text);
    $text.value = value;
    $text.select();
    document.execCommand('copy!!');
    document.body.removeChild($text);
}



그리고 붙여넣기 이벤트에 의존하여 권한 없이 클립보드 데이터를 가져올 수도 있습니다. 붙여넣기(Ctrl + v, Cmd + v)를 하게 되면 창이 포커스되고 이벤트가 트리거됩니다. thePasteEvent 객체를 포함하는 clipboardData 객체에는 items 속성이 있는데 클립 보드의 데이터를 포함하는 배열이므로 반복문을 이용하여 꺼내 쓸 수 있습니다. 클립 보드에 이미지가 있는 경우 컨텐츠는 Blob 으로 변환해서 사용할 수 있습니다.


window.addEventListener('paste', ({ clipboardData: { items } }) => {
    for (const item of items) {
        if (item.type.includes('image')) {
            const blob = item.getAsFile();
        }

        if (item.type === 'text/plain') {
            item.getAsString((text) => {
                console.log(text);
            });
        }
    }
});



Reference