> For the complete documentation index, see [llms.txt](https://docs.verge.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.verge.io/knowledge-base/zh/storage-vsan/nas-volume-browser-api.md).

# NAS 卷浏览器 API 参考

## 概述

{% hint style="info" %}
**要点**

* volume\_browser API 是 **异步的** - 创建一个任务，然后轮询结果
* 你 **必须** 包含 `?fields=id,status,result` 在轮询时需要包含，否则不会返回结果
* 使用空字符串 `""` 作为根目录路径（不是 `/`)
* 要浏览卷，NAS 服务 VM 必须正在运行
  {% endhint %}

该 `volume_browser` API 为 NAS 卷提供文件系统浏览功能。这对于自动化、集成以及构建自定义文件管理工具非常有用。

## 前提条件

* 一个正在运行的 NAS 服务，且至少有一个在线卷
* 具有适当权限的 API 访问
* 卷的 SHA1 密钥标识符（可在卷仪表板 URL 或 API 中找到）

## 工作原理

浏览卷是一个两步过程：

1. **POST** 更改为 `/api/v4/volume_browser` 用于创建浏览任务
2. **GET** 更改为 `/api/v4/volume_browser/{job_id}?fields=id,status,result` 用于轮询结果

## 步骤 1：创建浏览请求

### 端点

```
POST /api/v4/volume_browser
```

### 请求体

```json
{
  "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
  "query": "get-dir",
  "params": {
    "dir": "",
    "limit": 1000,
    "offset": null,
    "filter": {
      "extensions": ""
    },
    "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
    "sort": ""
  }
}
```

### 字段参考

| 字段       | 类型  | 必需 | 说明                                           |
| -------- | --- | -- | -------------------------------------------- |
| `volume` | 字符串 | 是  | 卷密钥（SHA1 哈希标识符）                              |
| `query`  | 字符串 | 是  | 操作类型： `get-dir`, `rename`, `delete`, `paste` |
| `params` | 对象  | 是  | 查询参数（见下文）                                    |

### Params 对象

| 字段                  | 类型      | 说明                      |
| ------------------- | ------- | ----------------------- |
| `dir`               | 字符串     | 要浏览的目录路径。使用 `""` 表示根目录。 |
| `limit`             | 整数      | 要返回的最大条目数（例如 1000）      |
| `offset`            | 整数/null | 分页偏移量， `null` 用于第一页     |
| `filter.extensions` | 字符串     | 按文件扩展名过滤（空字符串表示全部）      |
| `volume`            | 字符串     | 卷密钥（必须与顶层 `volume`)     |
| `sort`              | 字符串     | 排序字段（空字符串为默认值）          |

### 响应

```json
{
  "location": "/v4/volume_browser/9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "dbpath": "volume_browser/9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "$row": 1,
  "$key": "9a00434b882b9933512cc9d3abfd557a182d8fd3"
}
```

该 `$key` 字段包含轮询所需的任务 ID。

## 步骤 2：轮询结果

### 端点

```
GET /api/v4/volume_browser/{job_id}?fields=id,status,result
```

{% hint style="danger" %}
**关键：请求 Result 字段**

该 `result` 字段 **默认不会返回**。你必须显式使用 `?fields=id,status,result`请求它。没有此参数，你只会收到状态信息。
{% endhint %}

**不带 `?fields=id,status,result`:**

```json
{
  "id": "9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "query": "get-dir",
  "status": "complete",
  "command": ""
}
```

**带 `?fields=id,status,result`:**

```json
{
  "id": "9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "status": "complete",
  "result": [
    {"name": "documents", "size": 4096, "date": 1706120819, "type": "directory"},
    {"name": "file.txt", "size": 1024, "date": 1769198797, "type": "file"}
  ]
}
```

### 状态值

| 状态         | 说明                        |
| ---------- | ------------------------- |
| `running`  | 任务仍在处理                    |
| `complete` | 任务成功完成                    |
| `error`    | 任务失败（检查 `result` 以获取错误信息） |

### 轮询策略

```
1. 使用 POST 创建任务
2. 等待 200-500 毫秒
3. 使用 ?fields=id,status,result 发起 GET 请求
4. 如果 status == "running"，则等待并重试（最多 30 次）
5. 如果 status == "complete"，则处理结果
6. 如果 status == "error"，则处理错误
```

## 结果格式

当 `status` 是 `complete`， `result` 字段包含一个文件/目录条目数组：

```json
[
  {
    "name": "document.pdf",
    "n_name": "document.pdf",
    "size": 102400,
    "date": 1769136871,
    "type": "file"
  },
  {
    "name": "images",
    "n_name": "images",
    "size": 4096,
    "date": 1769197982,
    "type": "directory"
  }
]
```

### 条目字段

| 字段       | 类型  | 说明                       |
| -------- | --- | ------------------------ |
| `name`   | 字符串 | 文件或目录名称                  |
| `n_name` | 字符串 | 规范化名称（小写）                |
| `size`   | 整数  | 字节大小                     |
| `date`   | 整数  | 修改时间（Unix 时间戳）           |
| `type`   | 字符串 | `"file"` 或 `"directory"` |

### 空目录

对于空目录， `result` 将是一个空数组：

```json
{
  "id": "8cb12559b689f5a52472bd8882dde1c095b2ab64",
  "status": "complete",
  "result": []
}
```

## 示例

### cURL

```bash
# 步骤 1：创建浏览任务
JOB_ID=$(curl -s -X POST "https://your-vergeos.example.com/api/v4/volume_browser" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \\
  -d '{
    "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
    "query": "get-dir",
    "params": {
      "dir": "",
      "limit": 1000,
      "offset": null,
      "filter": {"extensions": ""},
      "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
      "sort": ""
    }
  }' | jq -r '."$key"')

# 步骤 2：轮询结果（重要：包含 fields 参数）
sleep 1
curl -s "https://your-vergeos.example.com/api/v4/volume_browser/${JOB_ID}?fields=id,status,result" \
  -H "Authorization: Bearer $TOKEN" | jq
```

### Python

```python
import requests
import time

def browse_volume(base_url, token, volume_key, path=""):
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }

    # 步骤 1：创建浏览任务
    payload = {
        "volume": volume_key,
        "query": "get-dir",
        "params": {
            "dir": path,  # 使用 "" 表示根目录
            "limit": 1000,
            "offset": None,
            "filter": {"extensions": ""},
            "volume": volume_key,
            "sort": ""
        }
    }

    response = requests.post(
        f"{base_url}/api/v4/volume_browser",
        headers=headers,
        json=payload,
        verify=False
    )
    job_id = response.json()["$key"]

    # 步骤 2：轮询结果
    for _ in range(30):
        time.sleep(0.5)

        # 重要：显式请求 result 字段
        response = requests.get(
            f"{base_url}/api/v4/volume_browser/{job_id}?fields=id,status,result",
            headers=headers,
            verify=False
        )
        data = response.json()

        if data["status"] == "complete":
            return data.get("result") or []
        elif data["status"] == "error":
            raise Exception(f"Browse failed: {data.get('result')}")

    raise TimeoutError("Browse operation timed out")
```

## 故障排除

{% hint style="warning" %}
**常见问题**

**结果字段为空或缺失**

* 你必须在 `?fields=id,status,result` 你的 GET 请求中包含
* 如果没有此参数，则只返回状态信息

**"VM 必须处于运行状态才能发起查询"**

* NAS 服务 VM 未运行
* 转到 NAS > NAS Services 并启动该服务

**"获取卷 VM 服务时出错：没有这样的文件或目录"**

* 该卷的 NAS 服务不存在或已被删除
* 验证该卷已关联到有效的 NAS 服务

**"未找到资源 '/v4/volume\_browser/'"**

* 轮询请求中的任务 ID 为空
* 确保你提取 `$key` 能从 POST 响应中正确提取
  {% endhint %}

### 常见错误

1. **使用 `路径` 而不是 `dir`** - 该字段名为 `dir`，而不是 `路径`
2. **将 params 作为 JSON 字符串发送** - 该 `params` 字段必须是对象，而不是 JSON 编码字符串
3. **缺少 params 字段** - 预期包含 params 对象中的所有字段
4. **忘记 `?fields=id,status,result`** - 没有这个，就不会返回文件数据

## 要求

* 要浏览卷，NAS 服务 VM 必须正在运行
* 卷必须在线（已挂载）
* 用户必须对该卷具有读取权限

## 其他资源

* [NAS 概览](/run-the-platform/nas/overview.md)
* [NAS 本地卷](/run-the-platform/nas/nas-local-volumes.md)
* [API 密钥](/run-the-platform/system-administration/api-keys.md)

## 反馈

{% hint style="info" %}
**需要帮助吗？**

如果你需要进一步帮助或对本文有任何疑问，请随时联系 [VergeOS 支持团队](/support-and-services.md).
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.verge.io/knowledge-base/zh/storage-vsan/nas-volume-browser-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
