Web Share API

W3C 권고안

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2023/REC-web-share-20230530/
최신 공개 버전:
https://www.w3.org/TR/web-share/
최신 편집자 초안:
https://w3c.github.io/web-share/
역사:
https://www.w3.org/standards/history/web-share
커밋 기록
테스트 스위트:
https://wpt.live/web-share/
구현 보고서:
https://w3c.github.io/web-share/imp-report/
편집자:
Matt Giuca (Google Inc.)
Eric Willigers (Google Inc.)
Marcos Cáceres (Apple Inc.)
피드백:
GitHub w3c/web-share (풀 리퀘스트, 새 이슈, 오픈 이슈)
정오표:
정오표 있음.
브라우저 지원:
caniuse.com

참고: 번역본.


요약

이 명세서는 텍스트, 링크 및 기타 콘텐츠를 사용자가 선택한 임의의 대상에 공유하기 위한 API를 정의합니다.

사용 가능한 공유 대상은 이 문서에서 명시하지 않으며, 사용자 에이전트가 제공합니다. 예를 들어 앱, 웹사이트 또는 연락처일 수 있습니다.

문서 상태

이 섹션은 본 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정판은 W3C 기술 보고서 색인 https://www.w3.org/TR/에서 확인할 수 있습니다.

이 문서는 웹 애플리케이션 워킹 그룹에서 권고 절차를 사용하여 권고안으로 발행되었습니다.

W3C는 이 명세서를 웹 표준으로 널리 배포할 것을 권장합니다.

W3C 권고안은 광범위한 합의 구축 후 W3C 및 회원사가 승인한 명세서로, 워킹 그룹 회원사의 로열티 프리 라이선스 이행 약속이 포함되어 있습니다. 향후 권고안의 업데이트에는 새로운 기능이 포함될 수 있습니다.

본 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C그룹 산출물과 관련된 공개 특허 목록을 관리합니다. 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 특정 특허에 실제로 해당하는 Essential Claim(s)가 있다고 판단되는 경우 W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

이 문서는 2021년 11월 2일 W3C 프로세스 문서에 따라 관리됩니다.

구현 현황

이 섹션은 비규범적입니다.

콘텐츠 공유 기능은 종종 기본 운영체제가 "공유" 기능을 제공하는지와 OS UI 관례에 따라 달라집니다. 예를 들어, 일부 운영체제는 "공유 시트"를 제공하고, 다른 운영체제는 팝업 메뉴를 사용합니다. 이러한 의존성으로 인해 Web Share API를 모든 OS에 적용하기 위한 구현자들의 작업이 진행 중입니다. 이 진행 상황은 구현 보고서의 실패 사례로 나타나며, 해당 보고서는 제한된 OS에서 테스트를 수행하여 생성됩니다. 그러나 워킹 그룹은 Web Share API가 시간이 지남에 따라 모든 OS에서 더 널리 사용될 것으로 낙관하고 있으며, 이미 다양한 기기의 인기 OS에서 널리 사용되고 있습니다.

1. 사용 예시

이 섹션은 비규범적입니다.

1.2 파일 공유

이 예시는 파일을 공유하는 방법을 보여줍니다. files 멤버는 배열이므로 여러 파일을 공유할 수 있습니다.

예시 2: 파일 공유
shareButton.addEventListener("click", async () => {
  const file = new File(data, "some.png", { type: "image/png" });
  try {
    await navigator.share({
      title: "Example File",
      files: [file]
    });
  } catch (err) {
    console.error("Share failed:", err.message);
  }
});

1.3 공유 유효성 검사

canShare() 메서드를 ShareData 딕셔너리와 함께 호출하면 공유 데이터의 유효성 검증을 수행합니다. share()와 달리, 일시적 활성화 없이 호출할 수 있습니다.

const file = new File([], "some.png", { type: "image/png" });

// 파일 지원 여부 확인
if (navigates.canShare({files: [file]})) {
  // png 파일 공유가 가능할 수 있습니다...
}

// 공유 가능한 URL인지 확인
if (navigates.canShare({ url: someURL })) {
  // URL이 유효하며 공유가 가능할 수 있습니다...
}

1.4 멤버 지원 여부 확인

WebIDL 딕셔너리 동작 특성상, 사용자 에이전트가 인식하지 못하는 멤버가 share()에 전달되면 무시됩니다. 여러 멤버를 공유할 때 사용자 에이전트가 일부 멤버를 지원하지 않을 경우 문제가 될 수 있습니다. 전달하는 모든 멤버가 지원되는지 확실히 하려면 각 멤버를 개별적으로 canShare()로 확인할 수 있습니다.

예시 4: 미래 호환 공유
const data = {
  title: "Example Page",
  url: "https://example.com",
  text: "This is a text to share",
  someFutureThing: "some future thing",
};
const allSupported = Object.entries(data).every(([key, value]) => {
  return navigator.canShare({ [key]: value });
});
if (allSupported) {
  await navigator.share(data);
}

또는, 지원되지 않는 멤버에 대해 UI 컴포넌트를 표시하지 않도록 애플리케이션 UI를 조정할 수 있습니다.

예시 5: 지원되지 않는 멤버 필터링
const data = {
  title: "Example Page",
  url: "https://example.com",
  text: "This is a text to share",
  someFutureThing: "some future thing",
};

// 지원되지 않는 멤버들
const unsupported = Object.entries(data).filter(([key, value]) => {
  return !navigator.canShare({ [key]: value });
});

1.5 서드파티 컨텍스트에서 API 활성화

기본 허용 목록'self'로 되어 있어 Web Share API는 기본적으로 퍼스트파티 컨텍스트에서만 사용할 수 있습니다.

서드파티에서는 iframeallow 속성으로 API 사용을 허용할 수 있습니다:

또는, 퍼스트파티 컨텍스트에서 HTTP 응답 헤더를 지정하여 API를 비활성화할 수 있습니다:

자세한 내용과 출처별 권한 정책 제어 방법은 Permissions Policy 명세서를 참고하세요.

2. API 정의

2.1 Navigator 인터페이스 확장

WebIDLpartial interface Navigator {
  [SecureContext] Promise<undefined> share(optional ShareData data = {});
  [SecureContext] boolean canShare(optional ShareData data = {});
};

2.1.1 내부 슬롯

이 API는 Navigator 인터페이스에 다음 내부 슬롯을 추가합니다.

Promise? [[sharePromise]]
this.[[sharePromise]]는 사용자가 일부 데이터를 공유 대상에 공유하려는 현재 의도를 나타내는 promise입니다. 처음에는 null로 초기화됩니다.

2.1.2 share() 메서드

share() 메서드가 data 인자를 받아 호출되면, 아래에 나열된 단계를 수행하며 다음의 보안 고려사항을 참고해야 합니다.

Web Share는 웹사이트에서 공유 대상으로 데이터를 전송할 수 있게 해줍니다. 공유 대상은 네이티브 애플리케이션일 수 있습니다. 이 기능은 Web Share에만 국한된 것은 아니지만, 기반 플랫폼에 따라 심각도가 달라질 수 있는 잠재적 보안 위험이 존재합니다.

share()로 전달된 데이터는 공유 대상의 버퍼 오버플로우 또는 원격 코드 실행 취약점을 악용하는 데 사용될 수 있습니다. 이에 대한 일반적인 방지 방법은 없지만, 구현자는 특히 파일 공유 시 이러한 가능성에 유의해야 합니다.

공유 대상이 공유된 URL을 참조하여 해당 정보를 전달할 경우, 원래는 비공개여야 할 정보가 의도치 않게 노출될 수 있습니다. 공유가 참조하는 콘텐츠가 해당 애플리케이션, 실행 호스트 또는 네트워크 위치에서만 접근 가능한 경우 정보 유출 위험이 커집니다.

악의적인 사이트는 공유 대상이 정보를 유출하는 것을 악용하여 궁극적으로 로컬 리소스(예: "file:" URL 또는 접근 불가한 로컬 서비스)로 해석되는 URL을 제공할 수 있습니다. 이 API가 공유 가능한 스킴을 제한하더라도, 리다이렉트나 URL의 호스트에 대한 DNS 조작을 통해 애플리케이션이 콘텐츠를 획득하도록 할 수 있습니다.

이러한 공격에 악용되지 않기 위해, 공유 대상은 URL을 소비, 콘텐츠를 가져와 처리하되 공유하지 않을 수도 있습니다. 예를 들어 사진 편집 앱에서는 "공유"된 이미지를 가져올 수 있습니다. 공유 대상은 콘텐츠를 가져오지 않고 URL만 공유할 수도 있습니다.

미리보기를 제공하거나 공유를 위해 콘텐츠를 가져오는 공유 대상은 정보 유출 위험이 있습니다. 미리보고 사용자가 승인한 콘텐츠는 안전할 수 있지만, 사용자가 정보의 비공개 여부를 항상 올바르게 판별할 수 있는 것은 아니므로, 어떤 콘텐츠든 공유하는 것은 위험이 있습니다. 특히 title은 공격자가 사용자를 속여 콘텐츠의 성격을 오해하게 만들 수 있습니다(자세한 내용은 5. 접근성 고려사항 참조).

DOMException을 사용하는 모든 기능과 마찬가지로, 구현자는 share()가 거부될 때 오류 메시지에 어떤 정보가 노출되는지 신중히 고려해야 합니다. 공유 대상의 유무와 사용자의 취소 여부를 구분하는 것만으로도, 사용자의 기기에 어떤 공유 대상이 설치되어 있는지에 관한 정보가 노출될 수 있습니다.

  1. globalthis관련 글로벌 객체로 설정합니다.
  2. documentglobal연결된 Document로 설정합니다.
  3. document완전히 활성화(full active) 상태가 아니면, "InvalidStateError" DOMException으로 reject된 promise를 반환합니다.
  4. documentweb-share 사용이 허용되지 않으면, "NotAllowedError" DOMException으로 reject된 promise를 반환합니다.
  5. this.[[sharePromise]]null이 아니면, "InvalidStateError" DOMException으로 reject된 promise를 반환합니다.
  6. global일시적 활성화(transient activation)가 없으면, "NotAllowedError" DOMException으로 reject된 promise를 반환합니다.
  7. 사용자 활성화 소진global에서 수행합니다.
  8. basethis관련 설정 객체API base URL로 설정합니다.
  9. validate share datadatabase로 실행한 결과가 false라면, TypeError로 reject된 promise를 반환합니다.
  10. dataurl 멤버가 있을 경우:
    1. urldataurlbase를 사용해 URL 파서를 실행한 결과로 설정합니다.
    2. Assert: urlURL입니다.
    3. data를 복사본으로 만든 후, url 멤버를 urlURL serializer를 실행한 결과로 설정합니다.
  11. 보안 고려로 인해 파일 타입이 차단될 경우, "NotAllowedError" DOMException으로 reject된 promise를 반환합니다.
  12. this.[[sharePromise]]새 promise로 설정합니다.
  13. this.[[sharePromise]]를 반환하고, 병렬로:
    1. 사용 가능한 공유 대상이 없다면, 글로벌 태스크를 큐에 추가하여 global을 사용해:
      1. reject this.[[sharePromise]]를 "AbortError" DOMException으로 reject합니다.
      2. this.[[sharePromise]]null로 설정합니다.
      3. 이 알고리즘을 종료합니다.
    2. 사용자에게 하나 이상의 공유 대상과 작업 중단 옵션을 선택할 수 있도록 합니다. 이 UI는 보안 확인 역할을 하여 웹사이트가 네이티브 앱으로 데이터를 무단 전송할 수 없게 합니다. 사용자 에이전트는 SHOULD OS 수준 UI에서 해당 기능을 제공하지 않을 경우, 사용자가 공유 내용을 검증할 수 있는 중간 UI를 표시해야 합니다.
    3. 사용자의 선택을 기다립니다.
    4. 사용자가 공유 작업을 중단한 경우, 글로벌 태스크를 큐에 추가하여 global을 사용해:
      1. reject this.[[sharePromise]]를 "AbortError" DOMException으로 reject합니다.
      2. this.[[sharePromise]]null로 설정합니다.
      3. 이 알고리즘을 종료합니다.
    5. 선택된 공유 대상을 활성화하고, data를 대상에 적합한 형식으로 변환하여 해당 대상에 전송합니다.
    6. 대상 실행 또는 데이터 전송 중 오류가 발생하면, 글로벌 태스크를 큐에 추가하여 global을 사용해:
      1. reject this.[[sharePromise]]를 "DataError" DOMException으로 reject합니다.
      2. this.[[sharePromise]]null로 설정합니다.
      3. 이 알고리즘을 종료합니다.
    7. 데이터가 공유 대상에 성공적으로 전송되거나, OS에 성공적으로 전송된 경우(공유 대상에의 전송 확인이 불가능한 경우), 글로벌 태스크를 큐에 추가하여 global을 사용해:
      참고
      1. resolve this.[[sharePromise]]undefined로 resolve합니다.
      2. this.[[sharePromise]]null로 설정합니다.

2.1.3 canShare(data) 메서드

canShare() 메서드를 ShareData data 인자와 함께 호출하면, 다음 단계를 실행합니다:

  1. documentthis관련 글로벌 객체연결된 Document로 설정합니다.
  2. document완전히 활성화 상태가 아니면, false를 반환합니다.
  3. documentweb-share 사용이 허용되지 않으면, false를 반환합니다.
  4. validate share datadatathis관련 설정 객체API base URL로 실행한 결과를 반환합니다.
참고: canShare()는 미래 호환성이 없습니다

2.1.4 공유 데이터 유효성 검사

공유 가능한 스킴(sharable scheme)은 다음 URL 스킴 중 하나입니다:

database공유 데이터 유효성 검사(validate share data)를 하려면, 다음 단계를 실행합니다:

  1. datatitle, text, url 또는 files 멤버 중 아무것도 없으면, false를 반환합니다.
  2. title, text, url 중 하나라도 있으면 titleTextOrUrl을 true로 설정합니다.
  3. datafiles 멤버가 있으면:
    1. titleTextOrUrl이 false이고, datafiles가 빈 배열이면 false를 반환합니다.
      참고

      { files: [] } 딕셔너리는 빈 딕셔너리로 처리됩니다. 하지만 {text: "text", files: []}와 같이 전달하면 files는 무시되므로 괜찮습니다.

    2. 구현이 파일 공유를 지원하지 않으면 false를 반환합니다.
    3. 사용자 에이전트가 files의 파일 중 하나라도 잠재적으로 악성 공유(예: 내용, 크기, 기타 특성상 악성으로 판단)로 간주하면 false를 반환합니다.
  4. dataurl 멤버가 있으면:
    1. urldataurl 멤버에 base를 사용하여 URL 파서를 실행한 결과로 설정합니다(인코딩 오버라이드 없음).
    2. url이 실패면 false를 반환합니다.
    3. url스킴로컬 스킴이거나, file, javascript, ws, wss이면 false를 반환합니다.
    4. url스킴공유 가능한 스킴이 아니면 false를 반환합니다.
  5. true를 반환합니다.

2.2 ShareData 딕셔너리

WebIDLdictionary ShareData {
  sequence<File> files;
  USVString title;
  USVString text;
  USVString url;
};

ShareData 딕셔너리는 여러 개의 선택적 멤버로 구성됩니다:

files 멤버
공유할 파일들입니다.
text 멤버
공유되는 메시지의 본문이 되는 임의의 텍스트입니다.
title 멤버
공유되는 문서의 제목입니다. 대상에 따라 무시될 수 있습니다.
url 멤버
공유되는 리소스를 참조하는 URL 문자열입니다.
참고

3. 공유 대상

공유 대상은 사용자 에이전트가 공유 데이터를 전송할 추상적인 목적지 개념입니다. 공유 대상의 정의는 사용자 에이전트의 재량에 따릅니다.

공유 대상은 ShareData를 직접 받아들일 수 없을 수도 있습니다(이 API를 고려하지 않고 작성된 경우). 하지만 반드시 MUST ShareData에 노출된 일부 또는 전체 개념에 대응하는 데이터를 받을 수 있어야 합니다. 공유 대상에 적합한 형식으로 데이터 변환을 하려면, 사용자 에이전트는 SHOULD ShareData의 멤버를 대상의 동등 개념에 매핑해야 하며, 필요하면 멤버를 버리거나 합칠 수도 있습니다 MAY. 페이로드 각 멤버의 의미는 공유 대상의 재량입니다.

참고
ShareData를 공유 대상(또는 운영체제)의 네이티브 형식에 매핑하는 것은 까다로울 수 있습니다. 일부 플랫폼은 동등한 멤버 집합이 없기 때문입니다. 예를 들어, 대상에 "text" 멤버만 있고 "URL" 멤버가 없다면(안드로이드가 그러함), texturl 멤버를 합쳐서 대상의 "text" 멤버로 전달할 수 있습니다.

각 공유 대상은 전달받는 ShareData 페이로드에 따라 조건부로 사용 가능해질 수 있습니다 MAY. 이 페이로드는 share() 메서드에 전달됩니다.

3.1 공유 대상 예시

이 섹션은 비규범적입니다.

공유 대상 목록은 사용자 에이전트와 호스트 운영체제에 따라 다양한 출처에서 채워질 수 있습니다. 예를 들면:

참고
마지막 경우를 위해 웹사이트가 공유 데이터를 받을 수 있도록 등록하는 표준화 시도도 있습니다. 자세한 내용은 Web Share Target을 참고하세요.

일부 경우에는 호스트 운영체제가 Web Share와 유사한 공유 또는 인텐트 시스템을 제공합니다. 이때는 사용자 에이전트가 공유 데이터를 운영체제에 바로 전달하고 네이티브 앱과 직접 통신하지 않을 수 있습니다.

4. Permissions Policy 통합

이 명세서는 "web-share"라는 문자열로 식별되는 정책 제어 권한을 정의합니다. 기본 허용 목록'self'이며, 이는 서드파티 컨텍스트가 기본적으로 API를 사용할 수 없음을 의미합니다.

사용자 에이전트가 Permissions PolicyPermissions-Policy HTTP 헤더를 지원하는 것은 OPTIONAL입니다.

개발자는 Permissions Policy 명세에서 제공하는 방법을 사용해 서드파티 컨텍스트가 이 API를 사용할 수 있는지 제어할 수 있습니다.

참고: Permissions Policy 구현 현황

5. 접근성 고려사항

이 섹션은 비규범적입니다.

이 명세가 사용자 인터페이스에 정보를 표시하는 데 사용될 때, 구현자는 해당 플랫폼의 OS 수준 접근성 지침을 따라야 합니다. 또한 공유는 최종 사용자에게 잠재적 보안 영향을 미칠 수 있으므로 share() 메서드의 일환으로 설명된 대로, 공유 UI는 접근성 있게 제공되어야 하며, 각 플랫폼의 보안 UI 지침도 고려해야 합니다. 주요 고려사항은 다음과 같습니다:

이러한 요소들은 시각, 운동, 인지 장애가 있는 사용자가 웹 페이지가 공유하는 콘텐츠의 성격을 더 잘 이해할 수 있도록 돕습니다.

6. 프라이버시 고려사항

7. 적합성

비규범적 마크가 된 섹션뿐 아니라, 이 명세서의 모든 저작 지침, 도표, 예시, 참고도 비규범적입니다. 그 외 모든 내용은 규범적입니다.

이 문서의 MAY, MUST, OPTIONAL, SHOULD 키워드는 BCP 14 [RFC2119] [RFC8174] 에 설명된 대로, 반드시 대문자로 표기된 경우에만 해당 의미로 해석됩니다.

8. IDL 색인

WebIDLpartial interface Navigator {
  [SecureContext] Promise<undefined> share(optional ShareData data = {});
  [SecureContext] boolean canShare(optional ShareData data = {});
};

dictionary ShareData {
  sequence<File> files;
  USVString title;
  USVString text;
  USVString url;
};

9. 변경 이력

이 섹션은 비규범적입니다.

다음은 권고안 제안(Proposed Recommendation) 단계에서 명세에 적용된 규범적 변경사항입니다. 전체 변경 내역은 커밋 로그를 참고하세요.

다음은 최초 공개 작업 초안(First Public Working Draft)에서 후보 권고안(Candidate Recommendation)까지 명세에 적용된 규범적 변경사항입니다. 전체 변경 내역은 커밋 로그를 참고하세요.

A. 감사의 글

편집자들은 명세 개선에 큰 기여를 한 다음 W3C 그룹들에 감사드립니다: Accessible Platform Architectures 워킹 그룹, Internationalization 워킹 그룹, Privacy Interest Group, 그리고 Technical Architecture Group.

Web Intents 팀에도 감사드립니다. 이들은 웹 앱 상호운용성(use case) 기초를 마련했습니다. 특히 Paul Kinlan은 Web Share 초기 옹호에 많은 기여를 했습니다.

B. 참고 문헌

B.1 규범 문헌

[fetch]
Fetch 표준. Anne van Kesteren. WHATWG. 현행 표준. URL: https://fetch.spec.whatwg.org/
[fileapi]
File API. Marijn Kruisselbrink. W3C. 2023년 2월 6일. W3C 작업 초안. URL: https://www.w3.org/TR/FileAPI/
[html]
HTML 표준. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[PERMISSIONS-POLICY]
Permissions Policy. Ian Clelland. W3C. 2023년 3월 22일. W3C 작업 초안. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFC에서 요구 수준을 표시하기 위한 키워드. S. Bradner. IETF. 1997년 3월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 키워드의 대소문자 모호성. B. Leiba. IETF. 2017년 5월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[url]
URL 표준. Anne van Kesteren. WHATWG. 현행 표준. URL: https://url.spec.whatwg.org/
[WEBIDL]
Web IDL 표준. Edgar Chen; Timothy Gu. WHATWG. 현행 표준. URL: https://webidl.spec.whatwg.org/

B.2 비규범 문헌

[encoding]
Encoding 표준. Anne van Kesteren. WHATWG. 현행 표준. URL: https://encoding.spec.whatwg.org/