본문 바로가기

구글 확장프로그램 개발하기 - 현재 페이지에 있는 이미지 다운로드

구글 확장프로그램으로 현재 페이지에 있는 이미지들을 다운로드하는 기능을 만들고 싶어, 서칭을 해보았지만 웹 기술의 고급용어들이 난무하던 것을 본 나는 쓰러질뻔 하였으나.. 간신히 정신을 부여잡고 개발을 하였습니다.

 

요구하는 기술

HTML, JavaScript

 

1. 요구사항 살피기

2. 로직 구상하기

3. 구현

4. 프로그램 업로드

5. 완성!

 

요구사항 살피기

현재 열려있는 페이지에 있는 이미지들을 빠르고 쉽게 다운로드 해버리기

 

로직 구상하기

다운로드 모듈

1. 일반적으로 웹페이지에서 이미지는 HTML 태그인 <img> 로 표현되고, 이미지의 저장 위치는 <img src="위치"> 이런 형태로 작성되므로 img 태그의 src 속성 값(url)들을 얻어온다.

2. 얻어온 src 값(url)에 다운로드 요청을 날린다.

 

구글 확장프로그램 UI 모듈

1. 확장 프로그램의 아이콘을 클릭하거나, 등록된 단축키로 호출하면 다운로드 모듈에 다운로드 해달라고 요청하는 기능을 만든다.

 

구현

폴더를 하나 만들고 위의 이름과 같이 파일을 생성합니다.

 

content.script.js

manifest.json

popup.html

popup.js

 

 

manifest.json

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
{
  "manifest_version": 3,
  "name": "Fast Image",
  "version": "1.0",
  "description": "Fast Image",
  "action": {
    "default_popup": "popup.html"
  },
  "commands": {
    "_execute_action": {
      "suggested_key": {
        "default": "Ctrl+C",
        "mac": "Command+C"
      }
    }
  },
  "permissions": [
    "activeTab"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content_script.js"]
    }
  ]
}
cs

 

manifest 파일에는 이 확장 프로그램의 이름, 권한, 단축키, 아이콘 등 현재 만들 프로그램에 대한 사항을 작성합니다. 

특이사항으로 컨트롤 + C를 누르면, 굳이 크롬 우측 상단에 위치한 확장 프로그램 아이콘을 클릭할 필요 없이 기능이 바로 실행할 수 있도록 하였습니다.

 

popup.html

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<head>
</head>
<body>
Fast Image
<script src="popup.js"></script>
</body>
</html>
cs

 

확장 프로그램 아이콘을 클릭했을 때 보여지는 팝업 UI를 HTML로 작성합니다.

 

popup.js

1
2
3
4
  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    const activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, { action: 'executeContentScript' });
  });
cs

 

팝업 UI에서 사용할 자바스크립트를 작성합니다.

확장 프로그램 내 executeConetntScript 액션에 등록된 함수들을 실행합니다.

 

popup.html에 <button onclick="다운로드요청함수"> 이렇게 작성하고popup.js에 onclick.listener에 등록하여 버튼을 눌렀을 때만 다운로드 요청을 하도록 할 수도 있습니다만 Fast Image이기 때문에 그런 번거로운 과정은 생략하여, popup이 열리는 순간 다운로드 하도록 하였습니다.

 

참고. popup.js는 다른 js 파일들 (content, background)과 상호작용 하는 역할을 맡고 있습니다. 

 

content_script.js

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 다운로드 요청 함수
function downloadFile(url) {
  fetch(url)
    .then(response => response.blob())
    .then(blob => {
      // 현재 시간으로 파일 이름 생성
      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2'0');
      const day = String(now.getDate()).padStart(2'0');
      const hour = String(now.getHours()).padStart(2'0');
      const minute = String(now.getMinutes()).padStart(2'0');
      const second = String(now.getSeconds()).padStart(2'0');
      const filename = `d_${year}${month}${day}_${hour}${minute}${second}.png`;
 
      // Blob 데이터를 파일로 다운로드하는 방법
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = filename;
      link.click();
      URL.revokeObjectURL(link.href);
    })
    .catch(error => console.error('다운로드 실패:', error));
}
 
function requestDowload(){
  // HTML에서 모든 <img> 태그를 가져옵니다.
  var sourceElements = document.querySelectorAll('img');
 
  // <img> 태그들의 src 속성 값을 가져와서 배열에 저장합니다.
  var srcValues = Array.from(sourceElements).map(source => source.getAttribute('src'));
 
  // src 값으로부터 다운로드 요청
  srcValues.forEach(src => {
    const absoluteURL = new URL(src, window.location.href).href;
    downloadFile(absoluteURL);
  });
}
 
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'executeContentScript') {
    requestDowload();
  }
});
 
cs

 

content_scrip.js는 현재 페이지와 DOM을 수행하므로 실제 로직을 작성합니다.

 

 

프로그램 업로드

크롬 우측 상단의 컨텐스트 메뉴를 열어 '확장 프로그램 관리'를 클릭합니다. 

 

'압축해제된 확장 프로그램을 로드합니다.' 클릭

 

생성한 폴더를 업로드 합니다. 업로드가 완료되면 프로그램 목록에 우측 이미지와 같이 등록 됩니다.

 

완성!

제가 작성한 포스팅 페이지로 들어가 잘 동작하는지 테스트를 해보겠습니다.

 

https://healp.tistory.com/107

 

Blazor 실행 시 HTTPS가 아닌 HTTP 프로토콜로 시작하는 방법

Blazor server app 기준입니다. 일반적으로 Blazor 프로젝트를 생성 시 HTTPS 프로토콜로 실행됩니다. HTTP 프로토콜로 실행해야 하는 경우 설정을 바꿔야 합니다. 프로젝트 탐색기에서 Properties/launchSetting

healp.tistory.com

 

이 상태에서 우측 상단의 아이콘을 눌러도 되고, 등록해둔 단축키 ( 컨트롤+C )를 눌러 실행합니다.

 

페이지 내 이미지 파일들이 순식간에 다운로드 되는 모습을 확인할 수 있습니다.

 

기타

- 현재는 png 파일을 대상으로 하므로 다른 확장자에 대해서 다운로드에 실패할 수 있습니다.

필요한 경우 분기를 작성하는 방법 등으로 여러 확장자에 대해 대응할 수 있게 할 수 있습니다.

 

- src값이 상대경로인 경우 동작을 안할 수 있습니다. 

(티스토리의 이미지는 절대경로를 사용하고 있습니다.)

상대경로 요것도 조금의 수정을 통하여 대응할 수 있을 것입니다. 

 

- img 태그 뿐아니라 video, source 태그로 부터 파일을 다운로드 하도록 할 수도 있습니다.

content_script.js에서 img 태그가 아닌 viedo, soruce 태그를 수집하는 것으로 바꾸고,

다운로드 요청 시 확장자를 적절하게 대응해주시면 됩니다.

 

마치며

현재 웹에 잠깐 발을 담구고 있다보니 이런 토이 프로젝트도 해보게 되었네요.

웹이 확실히 활용적이고 실용적인 면모가 있다보니 그런 점은 맘에 듭니다.

 

아! 단축키는 잘사용하지 않으면서도 누르기 편한 것으로 지정하는게 좋을 것 같습니다.

컨트롤 + C 로 지정해두었더니 복붙을 수행하기 힘들어졌네요

 

chrome://extensions/shortcuts

에서 단축키를 지정할 수도 있습니다.