このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

Clipboard: read() メソッド

Baseline 2024 *
Newly available

Since June 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Some parts of this feature may have varying levels of support.

安全なコンテキスト用: この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

read()Clipboard インターフェイスのメソッドで、クリップボードのコンテンツのコピーをリクエストし、返される Promise をそのデータで履行します。

このメソッドは、理論上、任意のデータを返すことができます(テキストしか返せない readText() とは異なります)。 ブラウザーでは一般的に、テキスト、HTML、PNG 画像データの読み取りに対応しています。

構文

js
read()
read(formats)

引数

formats 省略可

以下のプロパティを持つオプションのオブジェクトです。

unsanitized 省略可

文字列の配列 (Array) で、クリップボードから読み込む際に無害化が行われないデータ形式の MIME タイプが入ります。

ブラウザーによっては、悪意のあるコンテンツが文書に貼り付けられるのを防ぐため、クリップボードのデータを読み込む際に無害化処理を行う場合があります。例えば、Chrome(およびその他の Chromium ベースのブラウザー)では、<script> タグやその他の潜在的に危険なコンテンツを削除することで、HTML データを無害化します。unsanitized 配列を使用すると、無害化処理を行わない MIME タイプの一覧を指定することができます。

返値

クリップボードの内容が含まれている ClipboardItem オブジェクトの配列で解決する Promise です。

例外

NotAllowedError DOMException

クリップボードからの読み取りをすることができない場合に発生します。

セキュリティの注意事項

クリップボードからの読み取りは、保護されたコンテキストでのみ行うことができます。

その他のセキュリティ要件は、API の概要トピックにあるセキュリティの注意事項の節で網羅されています。

画像データの読み取り

この例では、read() メソッドを使用してクリップボードから画像データを読み取り、それを <img> 要素に貼り付けます。

HTML

html
<img id="source" src="butterfly.jpg" alt="A butterfly" />
<img id="destination" src="" alt="Pasted image" />
<button id="reload" type="button">再読み込み</button>
<p id="log"></p>

CSS

css
img {
  height: 100px;
  width: 100px;
  margin: 0 1rem;
  border: 1px solid black;
}
#reload {
  display: block;
  margin: 0 1rem;
}

JavaScript

このコードは、エラーを ID が log の要素にログ出力するための仕組みを提供します。

js
const logElement = document.querySelector("#log");
function log(text) {
  logElement.innerText = `Error: ${text}`;
}

同時に、「再読み込み」ボタンが押された際に、例を再読み込みしてクリアするコードも追加します。

js
const reload = document.querySelector("#reload");

reload.addEventListener("click", () => {
  window.location.reload(true);
});

残りのコードは、出力先要素がクリックされた際にクリップボードを読み取り、画像データを destinationImage 要素にコピーします。 read() メソッドが使用できない場合、またはクリップボードに PNG 形式のデータが含まれていない場合は、エラーをログに出力します。

js
const destinationImage = document.querySelector("#destination");
destinationImage.addEventListener("click", pasteImage);

async function pasteImage() {
  try {
    const clipboardContents = await navigator.clipboard.read();
    for (const item of clipboardContents) {
      if (!item.types.includes("image/png")) {
        throw new Error("クリップボードに PNG 画像データが入っていません。");
      }
      const blob = await item.getType("image/png");
      destinationImage.src = URL.createObjectURL(blob);
    }
  } catch (error) {
    log(error.message);
  }
}

結果

左側の蝶の画像をコピーするには、画像を右クリックし、コンテキストメニューから「画像をコピー」を選択してください。 次に、右側の空のフレームをクリックしてください。 この例では、クリップボードから画像データを取得し、空のフレームに画像を表示させます。

メモ: プロンプトが表示されたら、画像を貼り付けるための権限を付与してください。

クリップボードからデータの読み取り

この例では、read() メソッドを使用してクリップボードからデータを読み取り、クリップボードに格納されているデータをログ出力します。

このバージョンは前のものと異なり、画像だけでなく、テキスト、HTML、および画像の ClipboardItem オブジェクトも表示させるようになります。

HTML

html
<img id="source_jpg" src="butterfly.jpg" alt="JPG butterfly image" />
<div id="destination">ここをクリックすると、クリップボードにデータをコピーします。</div>
<button id="reload" type="button">再読み込み</button>
<p id="log"></p>

CSS

css
img {
  height: 100px;
  width: 100px;
  margin: 0 1rem;
  border: 1px solid black;
}

#destination {
  min-height: 300px;
  min-width: 90%;
  margin: 0 1rem;
  border: 1px solid black;
}

#reload {
  display: block;
  margin: 0 1rem;
}

JavaScript

このコードは、エラーを ID が log の要素にログ出力するための仕組みを提供します。

js
const logElement = document.querySelector("#log");
function log(text) {
  logElement.innerText = `Error: ${text}`;
}

同時に、「再読み込み」ボタンが押された際に、例を再読み込みしてクリアするコードも追加します。

js
const reload = document.querySelector("#reload");

reload.addEventListener("click", () => {
  window.location.reload(true);
});

残りのコードは、出力先要素がクリックされた際にクリップボードを読み取り、それぞれの ClipboardItem 要素とその MIME タイプを表示します。 read() メソッドが使用できない場合、またはクリップボードに他の MIME タイプが含まれている場合は、エラーをログに記録します。

js
const destinationDiv = document.querySelector("#destination");
destinationDiv.addEventListener("click", pasteData);

async function pasteData() {
  destinationDiv.innerText = ""; // 中身のテキストをクリア
  try {
    const clipboardContents = await navigator.clipboard.read();
    for (const item of clipboardContents) {
      for (const mimeType of item.types) {
        const mimeTypeElement = document.createElement("p");
        mimeTypeElement.innerText = `MIME タイプ: ${mimeType}`;
        destinationDiv.appendChild(mimeTypeElement);
        if (mimeType === "image/png") {
          const pngImage = new Image();
          pngImage.alt = "クリップボード内の PNG 画像";
          const blob = await item.getType("image/png");
          pngImage.src = URL.createObjectURL(blob);
          destinationDiv.appendChild(pngImage);
        } else if (mimeType === "text/html") {
          const blob = await item.getType("text/html");
          const blobText = await blob.text();
          const clipHTML = document.createElement("pre");
          clipHTML.innerText = blobText;
          destinationDiv.appendChild(clipHTML);
        } else if (mimeType === "text/plain") {
          const blob = await item.getType("text/plain");
          const blobText = await blob.text();
          const clipPlain = document.createElement("pre");
          clipPlain.innerText = blobText;
          destinationDiv.appendChild(clipPlain);
        } else {
          throw new Error(`${mimeType} には対応していません。`);
        }
      }
    }
  } catch (error) {
    log(error.message);
  }
}

結果

下記にあるテキストまたは蝶の画像 (JPG) をコピーしてください(画像をコピーするには、画像を右クリックし、コンテキストメニューから「画像をコピー」を選択してください)。 下記で示されたフレームを選択し、クリップボードからその情報をフレームに貼り付けてください。

メモ:

  • 蝶の画像が JPG ファイルであっても、クリップボードから読み込むと PNG になります。
  • プロンプトが表示された場合は、画像を貼り付けるために権限を与える必要があります。
  • サンプルフレームには、Permissions-Policyclipboard-read および clipboard-write 権限が与えられていないため、Chromium 系ブラウザーでは正常に動作しない可能性があります(Chromium 系ブラウザーでは必須)。

クリップボードからの無害化されていない HTML の読み取り

この例では、formats 引数を使用してクリップボードから HTML データを読み込み、ブラウザーによる事前処理を経ずに、コードを元の形式のまま取得します。

HTML

html
<textarea id="source" rows="5">
  <style>h1 {color: red;} p {color: blue;}</style>
  <h1>Hello world!</h1>
  <p>This is a test.</p>
  <script>alert('Hello world!');</script>
</textarea>
<button id="copy">HTML をコピー</button>
<button id="paste_normal">HTML を貼り付け</button>
<button id="paste_unsanitized">無害化されていない HTML を貼り付け</button>
<textarea id="destination" rows="5"></textarea>

CSS

css
body {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}

textarea {
  grid-column: 1 / span 3;
}

JavaScript

js
const copyButton = document.getElementById("copy");
const pasteButton = document.getElementById("paste_normal");
const pasteUnsanitizedButton = document.getElementById("paste_unsanitized");
const sourceTextarea = document.getElementById("source");
const destinationTextarea = document.getElementById("destination");

copyButton.addEventListener("click", async () => {
  const text = sourceTextarea.value;
  const type = "text/html";
  const blob = new Blob([text], { type });
  const data = [new ClipboardItem({ [type]: blob })];

  try {
    await navigator.clipboard.write(data);
  } catch (error) {
    destinationTextarea.value = `クリップボードへの書き込みに失敗: ${error}`;
  }
});

async function getHTMLFromClipboardContents(clipboardContents) {
  for (const item of clipboardContents) {
    if (item.types.includes("text/html")) {
      const blob = await item.getType("text/html");
      const blobText = await blob.text();
      return blobText;
    }
  }

  return null;
}

pasteButton.addEventListener("click", async () => {
  try {
    const clipboardContents = await navigator.clipboard.read();
    const html = await getHTMLFromClipboardContents(clipboardContents);
    destinationTextarea.value =
      html || "クリップボード内に HTML データが見つかりません。";
  } catch (error) {
    destinationTextarea.value = `クリップボードからの読み取りに失敗: ${error}`;
  }
});

pasteUnsanitizedButton.addEventListener("click", async () => {
  try {
    const clipboardContents = await navigator.clipboard.read({
      unsanitized: ["text/html"],
    });
    const html = await getHTMLFromClipboardContents(clipboardContents);
    destinationTextarea.value =
      html || "クリップボード内に HTML データが見つかりません。";
  } catch (error) {
    destinationTextarea.value = `クリップボードからの読み取りに失敗: ${error}`;
  }
});

結果

まず、「HTML をコピー」ボタンをクリックして、最初のテキストエリアの HTML コードをクリップボードにコピーしてください。その後、「HTML を貼り付け」ボタン、または「無害化されていない HTML を貼り付け」ボタンをクリックして、無害化された HTML コード、または無害化されていない HTM Lコードを 2 つ目テキストエリアに貼り付けてみてください。

仕様書

Specification
Clipboard API and events
# dom-clipboard-read

ブラウザーの互換性

関連情報