---
title: Notion Electron逆向工程：Clipboard-REA
url: https://rea.tools/zh-TW/showcase/notion/
---

[首頁](https://rea.tools/zh-TW/) / [案例展示](https://rea.tools/zh-TW/showcase/) / Notion

個案研究\*Electron

# 如何 Notion 複製 文字和HTML。

跟蹤剪貼簿呼叫從Notion的頁面API，透過預載入和主程序，到Electron的剪貼簿編寫器。

Notion桌面7.6.1·JavaScript\*REA

Notion 桌面包中的橋接程式碼

1. 01 · 面向頁面的API

   `clipboard.write(data)`

   預載入公開了一個可呼叫的方法。
2. 02 · 預載入包裝器

   `ipcRenderer.invoke`

   包裝器傳送通道和引數。
3. 03 · 主程序處理程式

   `ipcMain.handle`

   接收器檢查哪個頁面傳送它。
4. 04 · 系統剪貼簿

   `clipboard.write(data)`

   Electron 寫入提供的文字和HTML。

一個通道連線雙方: `notion:clipboard:write`

預載入指令碼和主程序使用同一個通道。解析包裝函式後，就能看出這些名稱背後實際呼叫的 Electron 函式。

## 複製操作去哪裡？

頁面可以呼叫名為 `clipboard.write` 的方法。它在預載入指令碼中的實現是一個包裝函式。關鍵問題是：它傳送了什麼，又由哪段程式碼接收？

你的程式設計助手

使用REA跟蹤Notion如何將文字和HTML複製到系統剪貼簿。 在每個步驟顯示程式碼。

一個示例提示與Notion的本地應用程式包可供你的程式設計助手.

### REA查詢從哪裡開始閱讀

用 REA 分析標籤頁的預載入指令碼，可以找到暴露給頁面的 API，以及傳送 IPC 請求的呼叫。兩個結果都給出了在壓縮程式碼中的位置：

REA 分析結果 → 兩個原始碼位置

公開頁面API

```
api_key: "__electronApi"
api_status: "dynamic"
source: preload.js:1:22764–22828
```

渲染器IPC呼叫

```
operation: "invoke"
channel_expression: "e"
source: preload.js:1:6486–6522
```

這是新一次 `analyze_javascript_application` 分析結果中的部分欄位，來自 Notion 標籤頁的預載入指令碼，使用 REA 4.1.0 記錄。位置對應原始壓縮包中的行號和從零開始的列號。

助手開啟這些位置，在組裝的 API 中找到剪貼簿成員，再讀取 `invokerInMain`。呼叫處傳入 `notion:clipboard:write`，讓助手知道要在主程序程式碼中搜尋哪個名稱。下面四段程式碼展示這條呼叫鏈。

### 四段簡短程式碼

從打包的JavaScript簡化，具有可讀的變數名稱。 不相關的成員被省略。

1. #### 從公開到頁面的API開始

   tab_browser_view/preload.js · API 成員

   ```
   const clipboardApi = {
     write: invokerInMain("notion:clipboard:write")
   };

   // Included in the API exposed through contextBridge:
   // window.__electronApi.clipboard
   ```

   此成員提供通道名稱。 的實施 `invokerInMain` 告訴我們請求如何離開頁面的程序。
2. #### 解析預載入的包裝器

   tab_browser_view/preload.js · IPC 輔助函式

   ```
   function invokerInMain(channel) {
     return (...args) => invokeInMainAndReturnResult(channel, ...args);
   }

   function invokeInMainAndReturnResult(channel, ...args) {
     return ipcRenderer.invoke(channel, ...args);
   }
   ```

   返回的函式透過 Electron 的請求／響應 IPC 轉發引數。接下來可以在主程序中查詢 `notion:clipboard:write`。
3. #### 檢查接收器是如何註冊的

   主要/index.js · 處理程式助手

   ```
   const handleRequestFromRenderer = {
     addListener(channel, handler) {
       ipcMain.handle(channel, handler);
     }
   };
   ```

   主程序使用另一個包裝器。 其 `addListener` 方法註冊一個 `ipcMain.handle` 那個頻道的接收器。
4. #### 查詢寫入及其發件人檢查

   主要/index.js · 剪貼簿接收器

   ```
   handleRequestFromRenderer.addListener(
     "notion:clipboard:write",
     (event, data) =>
       isNotionWebContents(event.sender)
         ? clipboard.write(data)
         : undefined
   );
   ```

   這就是呼叫的終點。處理函式檢查傳送方後，把收到的資料交給 Electron 的剪貼簿 API。通道名和兩個解析後的包裝函式，把暴露給頁面的方法連線到了這裡。

## 複製的塊如何保持其結構？

Notion 的網頁編輯器透過 `electronApi.clipboard.write` 傳送文字和 HTML。它在本地保留內容塊資料，再在複製的 HTML 中放入一個 ID，將二者關聯起來。

儲存的塊資料的HTML連結

傳送到系統剪貼簿

```
text: "Project notes"
html: "<p>Project notes</p>"
    + "<!-- notionvc: <copy-id> -->"
```

Notion本地儲存

```
id: <copy-id>
mimeTypes:
  text/_notion-blocks-v3-production
    → structured block data
```

1. 讀取HTML ID
2. 查詢相同的本地ID
3. 恢復Notion塊資料

文字和 ID 為示意值。已記錄的模組測試顯示：ID 匹配時可以取回內容塊資料；條目失效時只返回文字和 HTML。

在貼上時，Notion查詢HTML ID並根據儲存的複製進行檢查。 匹配的Id恢復所述塊資料。

從2026年7月13日快取的web資產中記錄的剪貼簿格式。

## 更多示例和來源

另一個例子：Markdown 表格

Notion將Markdown解析為塊資料。 此示例顯示錶如何成為標題和資料行。

透過Notion的Markdown解析器的表格

Markdown 輸入

```
| A | B |
| - | - |
| 1 | 2 |
```

結構化解析器輸出 · 摘錄

```
table · headerRow: true
  table_row
    cells: ["A"], ["B"]
  table_row
    cells: ["1"], ["2"]
```

從提取的Markdown解析器記錄輸出。 表變為行和單元格。


另一條路徑：離線SQLite連線

Notion 的渲染程序透過 IPC 請求 `getSqliteMeta`。主程序建立訊息通道，把一個埠交給渲染程序，另一個交給 SQLite 工具程序。後續的語句批次和結果直接透過這個埠傳輸。

追蹤這次交接，就能知道資料庫操作在哪個程序執行，也能解釋為什麼只跟蹤最初的 IPC 請求會漏掉後續通訊。


資料來源及如何閱讀摘錄

剪貼簿橋接程式碼來自 Notion Desktop 7.6.1 的 `app.asar`，包括標籤頁預載入指令碼和 `main/index.js`。節選中展開了壓縮後的變數名，並省略無關程式碼；傳送方檢查輔助函式展示了底層的 `isNotionWebContents` 呼叫。

虛擬剪貼簿和 Markdown 示例來自 2026 年 7 月 13 日快取的網頁資源，包括 `747001`、`58169`、`736810` 和 `422457` 模組。這些資源有獨立版本。儲存的測試執行提取出的模組和小型測試程式；輸出反映的是這些測試，沒有記錄桌面 UI 操作。

這裡的 REA 結果是對儲存的標籤頁預載入指令碼進行的專項分析，使用已釋出的 REA 4.1.0 記錄。它定位了 API 和呼叫操作。讀取包中的包裝函式實現後，就能把剪貼簿成員與匹配的接收方連線起來。

Markdown 示例使用解析器模組 `422457`。儲存的模組測試顯示，頁面和聊天過濾器都會保留這張表格。貼上／匯入、結構化標記和 AI／聊天解析器各自有不同入口與中間格式。

- [JavaScript應用指南](https://rea.tools/guides/javascript/)遵循一個小的Electron應用程式的匯出功能。
- [DX-Ball 重建工程](https://rea.tools/zh-TW/showcase/dx-ball/)按照原生說明檢查c函式。

[分析你自己的應用程式](https://rea.tools/get-started/)
