[comment]: # translation:outdated

[comment]: # ({96feb912-d3accdff})
# 1 其他 JavaScript 对象

[comment]: # ({/96feb912-d3accdff})

[comment]: # ({0a6cded7-ab8bd378})
### 概述

本节描述了使用Duktape实现的Zabbix对JavaScript语言的扩展，以及支持的[全局JavaScript函数](#global-javascript-functions)。

[comment]: # ({/0a6cded7-ab8bd378})

[comment]: # ({0a354bd3-c73f2449})
### 内置对象

[comment]: # ({/0a354bd3-c73f2449})

[comment]: # ({500e2fca-e5dc8dd0})
#### Zabbix

Zabbix 对象提供与 Zabbix 内部功能的交互。

| 方法 | 描述 |
| -- | -------- |
| `log(loglevel, message)` | 使用 <loglevel> 日志级别（参见配置文件中的 DebugLevel 参数）将 <message> 写入 Zabbix 日志。 |

示例：

```javascript
Zabbix.log(3, "this is a log entry written with 'Warning' log level")
```

你可以使用以下别名：

| 别名 | 别名对应的方法 |
| ----- | -------- |
| console.log(object) | Zabbix.log(4, JSON.stringify(object)) |
| console.warn(object) | Zabbix.log(3, JSON.stringify(object)) |
| console.error(object) | Zabbix.log(2, JSON.stringify(object)) |

::: noteimportant
每次脚本执行的所有日志消息的总大小限制为 8 MB。
:::

| 方法 | 描述 |
| -- | -------- |
| `sleep(delay)` | 延迟 JavaScript 执行 `delay` 毫秒。 |

示例（延迟执行 15 秒）：

```javascript
Zabbix.sleep(15000)
```

[comment]: # ({/500e2fca-e5dc8dd0})

[comment]: # ({57c385b7-413974f8})
#### HttpRequest

该对象封装了cURL句柄，允许进行简单的HTTP请求。
错误会被作为异常抛出。

::: noteimportant
每个脚本执行最多只能初始化10个`HttpRequest`对象。
:::

|方法|描述|
|--|--------|
|`addHeader(value)`|添加HTTP头字段。该字段将用于所有后续请求，直到使用`clearHeader()`方法清除。<br>可以向单个`HttpRequest`对象添加的所有头字段的总长度限制为128 K字节（包括特殊字符和头名称）。|
|`clearHeader()`|清除HTTP头。如果未设置任何头字段，`HttpRequest`将在发布的数据为JSON格式时将Content-Type设置为application/json；否则设置为text/plain。|
|`connect(url)`|向URL发送HTTP CONNECT请求并返回响应。|
|`customRequest(method, url, data)`|允许在第一个参数中指定任何HTTP方法。将指定的方法请求发送到URL，可选地带有*data*载荷，并返回响应。|
|`delete(url, data)`|向URL发送HTTP DELETE请求，可选地带有*data*载荷，并返回响应。|
|`getHeaders(<asArray>)`|返回接收到的HTTP头字段的对象。<br>`asArray`参数可以设置为"true"（例如，`getHeaders(true)`），"false"或未定义。如果设置为"true"，则接收到的HTTP头字段值将作为数组返回；应使用此选项检索多个同名头字段的字段值。<br>如果未设置或设置为"false"，则接收到的HTTP头字段值将作为字符串返回。|
|`get(url, data)`|向URL发送HTTP GET请求，可选地带有*data*载荷，并返回响应。|
|`head(url)`|向URL发送HTTP HEAD请求并返回响应。|
|`options(url)`|向URL发送HTTP OPTIONS请求并返回响应。|
|`patch(url, data)`|向URL发送HTTP PATCH请求，可选地带有*data*载荷，并返回响应。|
|`put(url, data)`|向URL发送HTTP PUT请求，可选地带有*data*载荷，并返回响应。|
|`post(url, data)`|向URL发送HTTP POST请求，可选地带有*data*载荷，并返回响应。|
|`getStatus()`|返回上次HTTP请求的状态代码。|
|`setProxy(proxy)`|将HTTP代理设置为"proxy"值。如果此参数为空，则不使用代理。|
|`setHttpAuth(bitmask, username, password)`|在'bitmask'参数中设置启用的HTTP身份验证方法（HTTPAUTH_BASIC，HTTPAUTH_DIGEST，HTTPAUTH_NEGOTIATE，HTTPAUTH_NTLM，HTTPAUTH_NONE）。<br>HTTPAUTH_NONE标志允许禁用HTTP身份验证。<br>示例：<br>`request.setHttpAuth(HTTPAUTH_NTLM \| HTTPAUTH_BASIC, username, password)`<br>`request.setHttpAuth(HTTPAUTH_NONE)`|
|`trace(url, data)`|向URL发送HTTP TRACE请求，可选地带有*data*载荷，并返回响应。|

示例：

```javascript
try {
    Zabbix.log(4, 'jira webhook script value='+value);
  
    var result = {
        'tags': {
            'endpoint': 'jira'
        }
    },
    params = JSON.parse(value),
    req = new HttpRequest(),
    fields = {},
    resp;
  
    req.addHeader('Content-Type: application/json');
    req.addHeader('Authorization: Basic '+params.authentication);
  
    fields.summary = params.summary;
    fields.description = params.description;
    fields.project = {"key": params.project_key};
    fields.issuetype = {"id": params.issue_id};
    resp = req.post('https://jira.example.com/rest/api/2/issue/',
        JSON.stringify({"fields": fields})
    );
  
    if (req.getStatus() != 201) {
        throw 'Response code: '+req.getStatus();
    }
  
    resp = JSON.parse(resp);
    result.tags.issue_id = resp.id;
    result.tags.issue_key = resp.key;
} catch (error) {
    Zabbix.log(4, 'jira issue creation failed json : '+JSON.stringify({"fields": fields}));
    Zabbix.log(4, 'jira issue creation failed : '+error);
  
    result = {};
}
  
return JSON.stringify(result);
```

[comment]: # ({/57c385b7-413974f8})

[comment]: # ({73df7bc5-06cac1ca})
#### XML

XML对象允许在项目和低级别发现预处理和webhook中处理XML数据。

::: noteimportant
为了使用XML对象，服务器/代理必须编译支持libxml2。
:::

|方法|描述|
|--|--------|
|`XML.query(data, expression)`|使用XPath检索节点内容。如果未找到节点，则返回null。<br>**expression** - XPath表达式；<br>**data** - XML数据字符串。|
|`XML.toJson(data)`|将XML格式的数据转换为JSON。|
|`XML.fromJson(object)`|将JSON格式的数据转换为XML。|

示例：

*输入：*

    <menu>
        <food type = "breakfast">
            <name>Chocolate</name>
            <price>$5.95</price>
            <description></description>
            <calories>650</calories>
        </food>
    </menu>

*输出：*

```json
{
    "menu": {
        "food": {
            "@type": "breakfast",
            "name": "Chocolate",
            "price": "$5.95",
            "description": null,
            "calories": "650"
        }
    }
}
```

[comment]: # ({/73df7bc5-06cac1ca})

[comment]: # ({9e03c929-a12fbdc2})
##### 序列化规则

XML转换为JSON将根据以下规则进行处理（对于JSON转换为XML，将应用相反的规则）：

1. XML属性将转换为具有其名称前缀为'@'的键。

示例：

*输入：*

     <xml foo="FOO">
       <bar>
         <baz>BAZ</baz>
       </bar>
     </xml>

*输出：*

```json
 {
   "xml": {
     "@foo": "FOO",
     "bar": {
       "baz": "BAZ"
     }
   }
 }
```

2. 自闭合元素（<foo/>）将被转换为值为'null'的元素。

示例：

*输入：*

    <xml>
      <foo/>
    </xml>

*输出：*

```json
{
  "xml": {
    "foo": null
  }
}
```

3. 空属性（具有""值的属性）将转换为具有空字符串('')值的属性。

示例：

*输入：*

    <xml>
      <foo bar="" />
    </xml>

*输出：*

```json
{
  "xml": {
    "foo": {
      "@bar": ""
    }
  }
}
```

4. 具有相同元素名称的多个子节点将转换为具有值数组的单个键。

示例：

*输入：*

    <xml>
      <foo>BAR</foo>
      <foo>BAZ</foo>
      <foo>QUX</foo>
    </xml>

*输出：*

```json
{
  "xml": {
    "foo": ["BAR", "BAZ", "QUX"]
  }
}
```

5. 如果文本元素既没有属性也没有子节点，则将其转换为字符串。

示例：

*输入：*

    <xml>
        <foo>BAZ</foo>
    </xml>

*输出：*

```json
{
  "xml": {
    "foo": "BAZ"
   }
}
```

6. 如果文本元素没有子节点但有属性，则将文本内容转换为键为'\#text'且内容为值的元素；属性将转换为序列化规则1中描述的属性。

示例：

*输入：*

    <xml>
      <foo bar="BAR">
        BAZ
      </foo>
    </xml>

*输出：*

```json
{
  "xml": {
    "foo": {
      "@bar": "BAR",
      "#text": "BAZ"
    }
  }
}
```

[comment]: # ({/9e03c929-a12fbdc2})

[comment]: # ({5c81b462-1368a2b0})
### 全局 JavaScript 函数

使用 Duktape 实现了额外的全局 JavaScript 函数：

-   `btoa(data)` - 将数据编码为 base64 字符串
-   `atob(base64_string)` - 解码 base64 字符串

```javascript
try {
    b64 = btoa("utf8 string");
    utf8 = atob(b64);
} 
catch (error) {
    return {'error.name' : error.name, 'error.message' : error.message}
}
```

-   `md5(data)` - 计算数据的 MD5 哈希值
-   `sha256(data)` - 计算数据的 SHA256 哈希值
-   `hmac('<hash type>', key, data)` - 返回作为十六进制格式字符串的 HMAC 哈希值；支持 MD5 和 SHA256 哈希类型；key 和 data 参数支持二进制数据。例如：
    -   `hmac('md5', key, data)`
    -   `hmac('sha256', key, data)`
-   `sign(hash, key, data)` - 返回计算的签名（使用 SHA-256 的 RSA 签名）作为字符串，其中：<br>
    **hash** - 仅允许 'sha256'，否则会抛出错误；<br>
    **key** - 私钥。应符合 PKCS#1 或 PKCS#8 标准。私钥可以采用不同形式提供：<br>
    -   用空格代替换行；
    -   用转义或非转义的 '\n' 代替换行；
    -   没有任何换行符作为单行字符串；
    -   作为 JSON 格式字符串。

    私钥还可以从用户宏/秘密宏/保管库中加载。

    **data** - 将被签名的数据。可以是字符串（也支持二进制数据）或缓冲区（Uint8Array/ArrayBuffer）。<br>
    使用 OpenSSL 或 GnuTLS 计算签名。如果 Zabbix 构建时没有任何这些加密库，会抛出错误（'缺少 OpenSSL 或 GnuTLS 库'）。

[comment]: # ({/5c81b462-1368a2b0})
