# SKILL: Web Space Uploader API (agent.php) 這是一支單檔 PHP API,讓 AI Agent 把做好的網頁 / 靜態檔案上傳到這個 web 空間並設定入口頁。 本文件為完整用法說明,讀完即可直接操作,不需要再猜測。 - API 端點:`https://website.jiapi.net/index.php` - 網站根位置(此 PHP 所在目錄的公開網址):`https://website.jiapi.net/` - 所有檔案都會被放在此 PHP 所在目錄底下的子目錄中。 --- ## 0. 回應格式 - **不帶任何參數** → 回傳這份 Markdown 純文字(`text/plain`)。 - **帶 `act` 參數** → 回傳 JSON(`application/json; charset=utf-8`)。 - JSON 使用 `JSON_UNESCAPED_UNICODE`,中文等 Unicode 直接輸出正常字元,**不會**變成 `\uXXXX`。 - 斜線 `/` 也不跳脫。輸出有做縮排美化。 - **唯一例外:`act=download` 成功時回傳的是二進位檔案串流**(`application/octet-stream` + `Content-Disposition: attachment`),**不是 JSON**。只有失敗時才會回 JSON 錯誤物件。 解析前請先看 `Content-Type`。 成功時的外層固定為: ```json { "ok": true, "act": "write", "data": { } } ``` 失敗時的外層固定為(HTTP 400 / 401 / 403 / 404 / 500): ```json { "ok": false, "act": "write", "error": "錯誤訊息" } ``` `ok` 恆為布林值;`act` 為正規化後的小寫動作名(無法辨識時為 `null`); 成功時所有內容都在 `data` 物件內,失敗時只有 `error` 字串。 **每個 act 的 `data` 欄位完整定義見第 11 節「回應欄位總表」。** --- ## 1. 參數總覽 | 參數 | 必要 | 說明 | |---|---|---| | `act` | 是 | 動作,見下表。大小寫不拘,內部會轉小寫。 | | `pwd` | 是 | 密碼。**所有 act 操作都必須帶密碼。** | | `folder` | 視 act | 專案目錄名稱(單層),相對於本 PHP 所在目錄。例:`folder=abc` → `./abc/` | | `path` | 視 act | 目錄內的相對路徑(含檔名)。`mock/a.txt` 與 `/mock/a.txt` 等價,皆從 `folder` 往下算。 | | `text` | `write` / `append_text` | 要寫入檔案的純文字內容(需 URL Encode)。 | ### act 一覽 | act | 用途 | 成功時回傳 | |---|---|---| | `list` | 列出 folder / 目錄內容 / 單一檔案資訊 | JSON | | `upload` | 上傳單一檔案(二進位,POST body) | JSON | | `write` | 用 `text` 寫入文字檔(**覆蓋**) | JSON | | `append_text` | 用 `text` 追加到檔案結尾(**不覆蓋**) | JSON | | `delete` | 刪除檔案或目錄 | JSON | | `redirect` | 建立 index.php 入口轉址 | JSON | | `download` | 下載檔案,或把目錄打包成 tar.gz 下載 | **二進位檔案** | ### 關於密碼 `pwd` 密碼由使用者自己保管,**本文件不揭露密碼**。 AI Agent 在第一次呼叫任何 `act` 之前,必須先向使用者詢問:「請提供上傳用的密碼」, 取得後放進每一次請求的 `pwd` 參數。密碼錯誤會回 HTTP 401。 ### 關於 `folder` - 只能是單層目錄名,允許字元 `A-Z a-z 0-9 . _ -`,第一個字元須為英數,長度 ≤ 64。 - 不存在時,`upload` / `write` / `append_text` / `redirect` 會自動建立。 - 建議一個專案用一個 folder,之後所有操作都在其下進行。 ### 關於 `path` - 一律相對於 `folder`,前面有沒有 `/` 都一樣。 - 可含多層子目錄,寫入時會自動遞迴建立中間目錄。 - **禁止** `..`(會回 400),無法跳出 `folder` 之外。 ### 關於 URL Encode(很重要) 所有參數值在放進 URL 前都必須做 **URL Encode**(percent-encoding, UTF-8): - 空白 → `%20`(或 `+`,在 query string 中兩者皆可被解回空白) - `&` → `%26`、`=` → `%3D`、`#` → `%23`、`+` → `%2B`、`%` → `%25` - 換行 `\n` → `%0A`、`\r` → `%0D` - 中文等 UTF-8 字元 → 例如「你好」→ `%E4%BD%A0%E5%A5%BD` 伺服器端會自動 URL Decode 還原成原始字串再寫入檔案。 > **⚠ 長度規則(實測後訂定,務必遵守)** > URL 有長度上限(各家瀏覽器/代理/工具不一,保守值約 2000 字元;部分工具低到 200)。 > 超過上限時,`text` 參數可能被**靜默丟棄**,結果是「API 回 ok、size 卻是 0」的假成功。 > > 因此: > - **編碼後的 `text` 超過約 100 字元,一律改用 POST**,不要用 GET。 > - POST 方式:`Content-Type: application/x-www-form-urlencoded`,把 `text` 放 POST body, > `act`/`pwd`/`folder`/`path` 仍放 query string。 > - 寫入 HTML / CSS / JS 這類檔案幾乎必定超過門檻,**預設就用 POST**。 > - 每次寫入後請檢查回應的 `size` 是否等於預期位元組數,`size` 為 0 或偏小即代表被截斷。 --- ## 2. act=list — 列出內容 | 傳入 | 行為 | `data.scope` | |---|---|---| | 只有 `act`+`pwd` | 列出本 PHP 目錄下的所有 folder(第一層目錄) | `root` | | 再加 `folder` | 列出該 folder 底下第一層的檔案與目錄 | `dir` | | 再加 `path`(指向目錄) | 列出該路徑底下第一層內容 | `dir` | | 再加 `path`(指向檔案) | 回傳該檔案的 UNIX 基本資料(等同 `ls -l`) | `file` | ``` GET https://website.jiapi.net/index.php?act=list&pwd= GET https://website.jiapi.net/index.php?act=list&pwd=&folder=abc GET https://website.jiapi.net/index.php?act=list&pwd=&folder=abc&path=mock GET https://website.jiapi.net/index.php?act=list&pwd=&folder=abc&path=mock/a.txt ``` 目錄內容一律「目錄在前、檔案在後」,各自依名稱排序。 ### 2a. scope = root ```json { "ok": true, "act": "list", "data": { "scope": "root", "base_url": "https://website.jiapi.net/", "count": 1, "items": [ { "name": "abc", "type": "dir", "size": 4096, "perms": "drwxr-xr-x", "mode": "0755", "uid": 141499303, "gid": 1049170745, "owner": "u141499303", "group": "o49170745", "nlink": 3, "mtime": "2026-08-07 14:11:26", "mtime_unix": 1786083086, "readable": true, "writable": true, "url": "https://website.jiapi.net/abc/", "has_index": true } ] } } ``` `has_index` 只在 scope=root 出現,代表該 folder 內已有 `index.php` 或 `index.html`。 ### 2b. scope = dir ```json { "ok": true, "act": "list", "data": { "scope": "dir", "folder": "abc", "path": "mock", "rel": "abc/mock", "url": "https://website.jiapi.net/abc/mock/", "count": 1, "items": [ { "name": "a.txt", "type": "file", "size": 5, "perms": "-rw-r--r--", "mode": "0644", "uid": 141499303, "gid": 1049170745, "owner": "u141499303", "group": "o49170745", "nlink": 1, "mtime": "2026-08-07 14:08:04", "mtime_unix": 1786082884, "readable": true, "writable": true, "url": "https://website.jiapi.net/abc/mock/a.txt" } ] } } ``` 目錄項目的 `url` 結尾會多一個 `/`。列 folder 根目錄時 `path` 為空字串、`rel` 等於 folder 名。 ### 2c. scope = file ```json { "ok": true, "act": "list", "data": { "scope": "file", "folder": "abc", "path": "mock/a.txt", "rel": "abc/mock/a.txt", "item": { "name": "a.txt", "type": "file", "size": 25, "perms": "-rw-r--r--", "mode": "0644", "uid": 141499303, "gid": 1049170745, "owner": "u141499303", "group": "o49170745", "nlink": 1, "mtime": "2026-08-07 14:08:04", "mtime_unix": 1786082884, "readable": true, "writable": true, "url": "https://website.jiapi.net/abc/mock/a.txt" } } } ``` 注意 scope=file 用的是單數的 `item` 物件,**沒有** `items` / `count` / `url`。 --- ## 3. act=upload — 上傳單一檔案(二進位) 一次上傳一個檔案。**多個檔案請遞迴/逐一呼叫。** 檔案內容放在 **POST body**,支援三種攜帶方式(擇一): ### 方式 A:raw binary body(建議,最省事) ```bash curl -X POST \ -H "Content-Type: application/octet-stream" \ --data-binary @./dist/index.html \ "https://website.jiapi.net/index.php?act=upload&pwd=&folder=abc&path=index.html" ``` ### 方式 B:multipart/form-data,欄位名 `file` ```bash curl -X POST \ -F "file=@./img/logo.png" \ "https://website.jiapi.net/index.php?act=upload&pwd=&folder=abc&path=img/logo.png" ``` ### 方式 C:base64(無法送二進位時) 欄位 `content_base64`,值為檔案內容的 base64 字串。GET / POST 皆可,但 GET 受 URL 長度限制。 ```bash curl -X POST \ --data-urlencode "content_base64=$(base64 -w0 ./img/logo.png)" \ "https://website.jiapi.net/index.php?act=upload&pwd=&folder=abc&path=img/logo.png" ``` 必要參數:`act=upload`、`pwd`、`folder`、`path`(含檔名)。 中間目錄不存在會自動建立。同名檔案會被覆蓋。 ```json { "ok": true, "act": "upload", "data": { "folder": "abc", "path": "img/logo.png", "rel": "abc/img/logo.png", "url": "https://website.jiapi.net/abc/img/logo.png", "size": 20480, "source": "raw", "overwritten": false } } ``` `source` 值為 `raw` / `multipart` / `base64`,代表伺服器實際採用了哪一種攜帶方式—— 可用來確認你的請求有被正確辨識。 --- ## 4. act=write — 寫入純文字(覆蓋) 用 `text` 參數寫入文字檔(HTML / CSS / JS / TXT / JSON 皆可)。**檔案已存在會整個覆蓋。** GET 只適合極短的內容(例如寫一個旗標檔): ``` GET https://website.jiapi.net/index.php?act=write&pwd=&folder=abc&path=mock/a.txt&text=HELLO ``` **其餘情況一律用 POST**(見第 1 節長度規則): ```bash curl -X POST \ --data-urlencode "text@./dist/index.html" \ "https://website.jiapi.net/index.php?act=write&pwd=&folder=abc&path=index.html" ``` - `text` 未提供時視為空字串(等於建立空檔案)。 - 一律以 UTF-8 位元組原樣寫入,不加 BOM、不改變換行。 - 中間目錄自動遞迴建立。 ```json { "ok": true, "act": "write", "data": { "folder": "abc", "path": "index.html", "rel": "abc/index.html", "url": "https://website.jiapi.net/abc/index.html", "size": 1837, "source": "text", "overwritten": true } } ``` 回應結構與 `upload` 完全相同,`source` 固定為 `text`,`size` 為寫入後的檔案總位元組數。 --- ## 5. act=append_text — 追加純文字(不覆蓋) 和 `write` 一樣用 `text` 參數,差別在於**不會覆蓋既有內容,而是接在檔案最後面**。 適合累積 log、逐段補寫長檔案、多次追加內容。 ```bash curl -X POST \ --data-urlencode "text=第二段內容" \ "https://website.jiapi.net/index.php?act=append_text&pwd=&folder=abc&path=notes.txt" ``` ### 換行規則 - 檔案**不存在** → 直接建立,內容就是 `text`(不會多加換行)。 - 檔案**已存在且結尾不是換行字元** → 先自動補一個 `\n`,再接上 `text`, 確保新內容從新的一行開始。 - 檔案**已存在且結尾已經是換行字元** → 不再補換行,直接接上 `text`(避免產生空白行)。 長度規則與 `write` 相同:超過約 100 字元請用 POST。 ```json { "ok": true, "act": "append_text", "data": { "folder": "abc", "path": "notes.txt", "rel": "abc/notes.txt", "url": "https://website.jiapi.net/abc/notes.txt", "source": "text", "existed": true, "separator_added": true, "bytes_written": 16, "size": 48 } } ``` | 欄位 | 意義 | |---|---| | `existed` | 追加前檔案是否已存在(`false` 代表這次是新建) | | `separator_added` | 這次是否自動補了一個換行字元 | | `bytes_written` | 本次實際寫入的位元組數(**含**自動補的換行) | | `size` | 追加後檔案的總位元組數 | 注意這裡**沒有** `overwritten` 欄位(`append_text` 永遠不覆蓋), 而 `write` / `upload` 則**沒有** `existed` / `separator_added` / `bytes_written`。 --- ## 6. act=delete — 刪除檔案或目錄 ``` GET https://website.jiapi.net/index.php?act=delete&pwd=&folder=abc&path=mock/a.txt # 刪單檔 GET https://website.jiapi.net/index.php?act=delete&pwd=&folder=abc&path=mock # 遞迴刪整個子目錄 GET https://website.jiapi.net/index.php?act=delete&pwd=&folder=abc # 清空 abc 內所有內容(folder 本身保留) ``` **限制:無法刪除 folder 本身。** 不帶 `path`(或 `path` 為空)時只會把 folder 清空, 目錄仍然存在。這是刻意的保護機制。 ```json { "ok": true, "act": "delete", "data": { "folder": "abc", "path": "mock", "target": "abc/mock", "mode": "recursive", "deleted": true } } ``` `mode` 有三種值: | `mode` | 情境 | |---|---| | `file` | `path` 指向單一檔案 | | `recursive` | `path` 指向目錄,連同底下所有內容一起刪除 | | `empty-folder` | 未提供 `path`,清空 folder 內容但保留 folder | `mode` 為 `empty-folder` 時會額外附帶 `note` 字串說明保護機制。 --- ## 7. act=redirect — 設定入口頁 在 `folder` 根目錄建立一支 `index.php`,訪問 `https://website.jiapi.net/abc/` 時自動 302 轉址到指定檔案。 ``` GET https://website.jiapi.net/index.php?act=redirect&pwd=&folder=abc&path=wrong.html ``` ```json { "ok": true, "act": "redirect", "data": { "folder": "abc", "path": "wrong.html", "index": "abc/index.php", "entry_url": "https://website.jiapi.net/abc/", "target_url": "https://website.jiapi.net/abc/wrong.html", "target_exists": true } } ``` - `index`:實際建立的檔案相對路徑,固定是 `/index.php`。 - `entry_url`:使用者要訪問的入口網址,回報給使用者時用這個。 - `target_url`:轉址的目的地完整網址。 - `target_exists`:目標檔案目前是否存在。若為 `false`,仍會建立 index.php, 但會**額外附帶 `warning` 字串**提醒你還沒上傳該檔案。 - `path` 不可指向 `index.php` 本身(會造成無限轉址,回 400)。 --- ## 8. act=download — 下載檔案或打包目錄 **這個 act 成功時回傳的是檔案本身,不是 JSON。** 只有出錯時才回 JSON 錯誤物件。 | 傳入 | 行為 | 下載檔名 | |---|---|---| | `folder` + `path` 指向檔案 | 直接下載該檔案(強制附件下載,不會用瀏覽器開啟) | 原檔名 | | `folder` + `path` 指向目錄 | 打包成 tar.gz 後下載 | `<目錄名>.tar.gz` | | 只有 `folder` | 打包整個 folder | `.tar.gz` | ```bash # 下載單一檔案(即使是 .html 也會是下載而非開啟) curl -OJ "https://website.jiapi.net/index.php?act=download&pwd=&folder=abc&path=index.html" # 打包下載整個 folder curl -OJ "https://website.jiapi.net/index.php?act=download&pwd=&folder=abc" # 打包下載某個子目錄 curl -OJ "https://website.jiapi.net/index.php?act=download&pwd=&folder=abc&path=img" ``` `curl -OJ` 會採用伺服器給的 `Content-Disposition` 檔名。 ### 回應標頭 - `Content-Type: application/octet-stream`(一律強制下載,`.html` 也不會被瀏覽器開啟) - `Content-Disposition: attachment; filename="..."` - 檔名為非 ASCII(例如中文目錄名)時,會**同時**帶上 RFC 5987 的 `filename*=UTF-8''<百分比編碼>`,瀏覽器會優先採用它以保留原始名稱; 不支援的用戶端則退回 ASCII 版本(非 ASCII 字元被換成 `_`)。 - `Content-Length`、`X-Content-Type-Options: nosniff`、`Cache-Control: no-store` ### 打包細節 - tar.gz 產生在本 PHP 所在目錄下的 `./tmp/`,檔名為隨機 hash(避免被猜到)。 - 壓縮檔內最上層會包一層原始目錄名的資料夾(解開後是 `abc/...` 而不是散落一地)。 - 檔案送出後即刪除暫存檔;若傳輸中斷造成殘留,下次呼叫 `download` 時會自動清掉 超過 1 小時的暫存檔。 - `./tmp/` 是內部工作目錄,**不會**出現在 `act=list` 的 folder 清單中。 - 空目錄無法打包,會回 400。 ### 失敗時(回 JSON) ```json { "ok": false, "act": "download", "error": "path 不存在:abc/nope" } ``` **AI Agent 解析建議**:先檢查 HTTP 狀態碼與 `Content-Type`。 `application/json` → 當作錯誤處理;`application/octet-stream` → 當作檔案內容存檔。 --- ## 9. 錯誤碼 | HTTP | 意義 | |---|---| | 400 | 參數錯誤(缺參數、folder 名稱不合法、path 含 `..`、未知 act、打包空目錄、redirect 指向 index.php) | | 401 | `pwd` 錯誤或未提供 | | 403 | 檔案系統權限不足,無法建立目錄/寫入/刪除 | | 404 | 指定的 folder / path 不存在 | | 500 | 伺服器端寫入或打包失敗 | 失敗回應一律是 `{"ok": false, "act": "...", "error": "..."}`,沒有 `data` 欄位。 --- ## 10. AI Agent 標準作業流程(照這個做) 1. **問密碼**:向使用者索取上傳密碼,之後每次請求都帶在 `pwd`。 2. **問 folder**:向使用者確認這次專案要用的目錄名稱(例如 `myapp`)。 可先呼叫 `act=list` 看看現有有哪些 folder,避免撞名或確認要覆蓋。 3. **上傳檔案**:對做好的每一個檔案逐一呼叫 - 純文字(html/css/js/json/txt)→ `act=write`,**用 POST 送 `text`**(GET 只夠塞極短內容) - 需要分次補寫同一個檔案 → 第一次 `write`,後續用 `act=append_text` - 二進位(圖片、字型、壓縮檔)→ `act=upload`(POST raw binary) - 保持與本機一致的相對路徑,例如 `index.html`、`assets/app.js`、`img/logo.png`。 - **每次都核對回應的 `size`**,不等於預期位元組數就是被截斷,必須重傳。 4. **設定入口**:判斷入口檔案(通常是 `index.html`)。若檔名不是 `index.html`, 或想確保 `/folder/` 直接可用,就問使用者要用哪個檔案當入口(或自行判斷後告知), 然後呼叫 `act=redirect&folder=&path=<入口檔>`。 5. **驗收**:呼叫 `act=list&folder=` 確認檔案都在, 把入口網址 `https://website.jiapi.net//` 回報給使用者。 6. **(需要時)備份**:`act=download&folder=` 可把整個專案打包成 tar.gz 取回。 ### 完整範例 ```bash E="https://website.jiapi.net/index.php" P="<使用者提供的密碼>" F="myapp" # 1) 寫入 HTML(用 POST,避免 URL 長度上限造成靜默截斷) curl -sX POST --data-urlencode "text@./dist/index.html" "$E?act=write&pwd=$P&folder=$F&path=index.html" # 2) 追加一段內容到既有檔案 curl -sX POST --data-urlencode "text=" "$E?act=append_text&pwd=$P&folder=$F&path=index.html" # 3) 上傳圖片 curl -sX POST -H "Content-Type: application/octet-stream" \ --data-binary @./dist/img/logo.png "$E?act=upload&pwd=$P&folder=$F&path=img/logo.png" # 4) 設定入口 curl -s "$E?act=redirect&pwd=$P&folder=$F&path=index.html" # 5) 檢查 curl -s "$E?act=list&pwd=$P&folder=$F" # 6) 打包取回 curl -OJ "$E?act=download&pwd=$P&folder=$F" ``` --- ## 11. 回應欄位總表 所有成功回應都是 `{"ok":true,"act":"","data":{...}}`,下表列出各 act 的 `data` 內容。 型別:`str` 字串、`int` 整數、`bool` 布林、`obj` 物件、`arr` 陣列、`null` 可能為 null。 ### 共用:檔案/目錄項目物件(list 的 `items[]` 與 `item`) | 欄位 | 型別 | 說明 | |---|---|---| | `name` | str | 檔名或目錄名(不含路徑) | | `type` | str | `file` 或 `dir` | | `size` | int | 位元組數;目錄為該 inode 大小(通常 4096) | | `perms` | str | `ls -l` 格式權限字串,例如 `-rw-r--r--`、`drwxr-xr-x` | | `mode` | str | 八進位權限後四碼,例如 `0644` | | `uid` | int\|null | 擁有者數字 ID | | `gid` | int\|null | 群組數字 ID | | `owner` | str | 擁有者名稱;系統不支援 posix 函式時為空字串 | | `group` | str | 群組名稱;同上 | | `nlink` | int\|null | 硬連結數 | | `mtime` | str | 修改時間 `Y-m-d H:i:s`(時區 Asia/Taipei) | | `mtime_unix` | int\|null | 修改時間 Unix timestamp | | `readable` | bool | PHP 是否可讀 | | `writable` | bool | PHP 是否可寫 | | `url` | str | 公開網址;目錄結尾帶 `/` | | `has_index` | bool | **僅 scope=root 出現**,該 folder 內是否已有 index.php 或 index.html | ### act=list | scope | `data` 欄位 | |---|---| | `root` | `scope`(str) `base_url`(str) `count`(int) `items`(arr of 項目物件) | | `dir` | `scope`(str) `folder`(str) `path`(str) `rel`(str) `url`(str) `count`(int) `items`(arr) | | `file` | `scope`(str) `folder`(str) `path`(str) `rel`(str) `item`(obj 單一項目物件) | `path` 為正規化後的相對路徑(去掉前導 `/`);`rel` 為 `folder/path` 合併後的相對路徑。 ### act=upload / act=write | 欄位 | 型別 | 說明 | |---|---|---| | `folder` | str | folder 名稱 | | `path` | str | 正規化後的相對路徑(含檔名) | | `rel` | str | `folder/path` | | `url` | str | 檔案的公開網址 | | `size` | int | 寫入後的檔案總位元組數 | | `source` | str | `raw` / `multipart` / `base64` / `text` | | `overwritten` | bool | 是否覆蓋了既有檔案 | ### act=append_text | 欄位 | 型別 | 說明 | |---|---|---| | `folder` | str | folder 名稱 | | `path` | str | 正規化後的相對路徑(含檔名) | | `rel` | str | `folder/path` | | `url` | str | 檔案的公開網址 | | `source` | str | 固定為 `text` | | `existed` | bool | 追加前檔案是否已存在 | | `separator_added` | bool | 是否自動補了換行 | | `bytes_written` | int | 本次寫入位元組數(含補的換行) | | `size` | int | 追加後檔案總位元組數 | ### act=delete | 欄位 | 型別 | 說明 | |---|---|---| | `folder` | str | folder 名稱 | | `path` | str | 正規化後的相對路徑;清空 folder 時為空字串 | | `target` | str | 實際被刪除的相對路徑 | | `mode` | str | `file` / `recursive` / `empty-folder` | | `deleted` | bool | 恆為 `true`(失敗會走錯誤回應) | | `note` | str | **僅 `mode=empty-folder` 出現**,說明 folder 本身受保護 | ### act=redirect | 欄位 | 型別 | 說明 | |---|---|---| | `folder` | str | folder 名稱 | | `path` | str | 轉址目標的相對路徑 | | `index` | str | 產生的 index.php 相對路徑 | | `entry_url` | str | 入口網址(回報給使用者用這個) | | `target_url` | str | 轉址目的地完整網址 | | `target_exists` | bool | 目標檔案是否已存在 | | `warning` | str | **僅 `target_exists=false` 出現**,提醒尚未上傳目標檔案 | ### act=download 成功時**沒有 JSON**,直接是檔案串流;失敗時為標準錯誤物件 `{ok:false, act:"download", error:"..."}`。 --- ## 12. 注意事項 - 單檔上傳大小受主機 `upload_max_filesize` / `post_max_size` 限制,過大請分檔或壓縮。 - `folder` 是單層;要多層結構請用 `path`(例如 `path=sub/dir/file.html`)。 - 本 PHP 檔本身不會出現在 `act=list` 的 folder 清單中,也無法被刪除。 - `./tmp/` 為 download 打包用的內部暫存目錄,同樣不會出現在 folder 清單中。 - 這支 API 僅供擁有者本人使用,請勿外流密碼。