# 声明式网络请求规则

> 通过 Extended Preferences 或 Provision 规则文件安装固定的阻止、重定向和允许规则。

Source: https://console.getchrovia.com/zh/docs/sdk-declarative-net-request

**能力：**`declarativeNetRequest`。**配置：**`internal.declarative_net_request.rules` 和/或 `<Provision 根目录>/dnr_rules.json`。这是内核固定规则，不是调用扩展的动态规则 API。

## 添加 EP 规则

```json
{
  "internal": {
    "declarative_net_request": {
      "rules": [
        {
          "id": 1,
          "priority": 1,
          "action": { "type": "block" },
          "condition": {
            "urlFilter": "||example.com/sdk-block",
            "resourceTypes": ["main_frame"]
          }
        }
      ]
    }
  }
}
```

合并文档并按需签名。完全重启后访问 `https://example.com/sdk-block` 验证阻止。条件使用 Chromium DNR 语法，**不是** `network.intercept()` 和 `navigation_redirect` 的通配语法。

## 选择匹配条件

字段语法参见 [RuleCondition 参考](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-RuleCondition)，目标选项参见 [Redirect 参考](https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-Redirect)。同时遵守下方 Chrovia 限制，这里并非支持所有 Chrome 扩展规则选项。

| 字段 | 用法 |
| --- | --- |
| `urlFilter` | DNR URL 过滤字符串；`*` 是通配符，`^` 匹配分隔符或 URL 末尾，上例的双竖线前缀用于限定主机名 |
| `regexFilter` | RE2 正则表达式；与 `urlFilter` 二选一，不要同时使用 |
| `isUrlFilterCaseSensitive` | 布尔值，默认 false |
| `requestDomains`、`excludedRequestDomains` | 目标域名数组，也匹配子域名 |
| `initiatorDomains`、`excludedInitiatorDomains` | 请求发起方域名数组，不一定是目标主机 |
| `resourceTypes`、`excludedResourceTypes` | 资源类型数组，例如 `main_frame`、`sub_frame`、`script`、`image`、`xmlhttprequest` |
| `requestMethods`、`excludedRequestMethods` | 小写方法数组，例如 `get`、`post` |
| `domainType` | `firstParty` 或 `thirdParty`，省略则两者都匹配 |

填写的条件必须全部匹配。固定规则不支持按标签页过滤，不要使用 `tabIds` 或 `excludedTabIds`。需要覆盖顶层导航时，应明确包含 `main_frame`。

例如，以下独立 Provision 规则数组只阻止发往 API 主机的 POST 请求：

```json
[
  {
    "id": 2,
    "priority": 1,
    "action": { "type": "block" },
    "condition": {
      "requestDomains": ["api.example.com"],
      "requestMethods": ["post"],
      "resourceTypes": ["xmlhttprequest"]
    }
  }
]
```

## 动作与优先级

| 动作 | 配置 |
| --- | --- |
| `block` | `{"type":"block"}` |
| `redirect` | `{"type":"redirect","redirect":{"url":"https://example.org/"}}` |
| `allow` | `{"type":"allow"}`，可覆盖较低优先级的匹配固定阻止规则 |

规则 ID 使用跨 EP 与 Provision 唯一的正整数，并明确设置正整数优先级。允许例外应具有高于阻止规则的优先级。明确设置 `resourceTypes`；`main_frame` 不覆盖所有子资源。

只支持 `block`、`redirect`、`allow`。不支持 `allowAllRequests`、`upgradeScheme`、`modifyHeaders` 或重定向的 `extensionPath`。

重定向可使用 `redirect.url` 指定固定绝对目标，使用 `redirect.transform` 修改 URL 的部分内容，或将 `redirect.regexSubstitution` 与 `regexFilter` 条件配合使用。每条规则只选择一种目标形式。例如，`{"type":"redirect","redirect":{"transform":{"scheme":"https","host":"example.org"}}}` 修改这两部分并保留其余 URL 内容。条件应限定原主机，避免循环重定向。

## 通过 Provision 分发

安装级规则放在 `dnr_rules.json` 中，内容是**规则数组本身**，不是包含 `internal` 或 `rules` 的对象：

```json
[
  {
    "id": 1001,
    "priority": 1,
    "action": { "type": "block" },
    "condition": {
      "urlFilter": "||example.com/sdk-install-block",
      "resourceTypes": ["main_frame"]
    }
  }
]
```

两种文件都需要 `declarativeNetRequest`。单独限制对 `dnr_rules.json` 的访问；使用已签名 EP 不会阻止该文件被编辑。

安装或更新浏览器包后，确认 `dnr_rules.json` 位于该安装实际使用的 Provision 根目录，与 `Extensions` 并列，不要放进插件目录。参见 [Provision 打包](https://console.getchrovia.com/zh/docs/sdk-provision)。

## 限制与排查

修改固定规则后应完全重启，没有用于实时更新的 Chrovia JS 方法。格式错误的项会跳过并记录日志。规则无效或超过规则限制可能使规则集无法加载。不支持的动作不会自动变成阻止。

核对实际 URL、资源类型、ID 唯一性、优先级、License 和 EP 签名。固定规则不依赖运行中的 Service Worker 回调。只有需要每个请求由应用作决定时，才使用[网络拦截](https://console.getchrovia.com/zh/docs/sdk-network-intercept)。
