You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Prometheus HTTP API时Curl与Node.js请求结果差异求助

Prometheus API调用结果差异问题排查

问题现象

调用Prometheus HTTP API时,两种方式返回结果完全不同:

  • Bash+curl调用返回正常的vector类型监控数据
  • Node.js+https GET调用返回string类型,结果为查询语句本身

1. Bash+curl 调用示例

调用代码

#!/bin/bash
APIKEY="xxx-xxx"

curl https://<server>/prometheus-api/query \
-H "x-api-key: $APIKEY" \
-H "content-type: application/x-www-form-urlencoded" \
--data-urlencode \
query='ifHCInOctets{instance="MYROUTER.xxx"} and ifHCInOctets{ifName=~"et-1/1/1"}'

返回结果

{
  "status": "success",
  "data": {
    "resultType": "vector",
    "result": [
      {
        "metric": {
          "__name__": "ifHCInOctets",
          "ifAlias": "--- Lien vers ...",
          "ifDescr": "et-1/1/1",
          "ifIndex": "682",
          "ifName": "et-1/1/1",
          "instance": "MYROUTER.xxx",
          "job": "ifmibsnmp"
        },
        "value": [
          1725001024.046,
          "1975177966081341"
        ]
      }
    ]
  }
}

2. Node.js+https 调用示例

调用代码

var request = '/prometheus-api/query?query=\"ifHCInOctets{instance=\'MYROUTER.xxx\'} and ifHCInOctets{ifName=~\'et-1/1/1\'}\"'

var erequest = encodeURI(request)

var options = {
    host:host,
    port: 443,
    method: "GET",
    path: erequest,
    headers: {
      'x-api-key': 'xxxxx',
      'content-type': 'application/x-www-form-urlencoded',
    },
    rejectUnauthorized: false,
}
https.get(options,function(resp) {
  resp.setEncoding('utf8');
  console.log('statusCode',resp.statusCode)
  if(resp.statusCode!=200) {
    console.log('-----------------')
  }
  let data = '';
  resp.on('data',function(chunk) {
    data += chunk;
  });
  resp.on('end', () => {
    exec.emit('data',data)
  });
}).on('error', (err) => {
  console.log('Error: ' + err.message);
});

返回结果

{
  "status": "success",
  "data": {
    "resultType": "string",
    "result": [
      1725001330.179,
      "ifHCInOctets{instance='MYROUTER.xxx'} and ifHCInOctets{ifName=~'et-1/1/1'}"
    ]
  }
}

问题原因

Node.js代码存在两处关键错误:

  • 多余转义字符:request变量里给查询语句套了转义双引号,导致Prometheus把传入的内容识别为字符串字面量,而非查询表达式
  • 错误编码范围:对整个路径(包含?和=)执行encodeURI,导致API无法正确解析查询参数,应该仅对查询参数的值单独编码

修复方案

修改Node.js代码,正确处理查询参数的转义和编码:

// 定义原始查询语句,无需额外转义
const query = 'ifHCInOctets{instance="MYROUTER.xxx"} and ifHCInOctets{ifName=~"et-1/1/1"}';
// 仅对查询参数的值进行编码
const encodedQuery = encodeURIComponent(query);
// 拼接正确的请求路径
const path = `/prometheus-api/query?query=${encodedQuery}`;

const options = {
    host: host,
    port: 443,
    method: "GET",
    path: path,
    headers: {
      'x-api-key': 'xxxxx',
      // GET请求无需设置content-type头,可移除
    },
    rejectUnauthorized: false,
};

https.get(options, function(resp) {
  resp.setEncoding('utf8');
  console.log('statusCode', resp.statusCode);
  let data = '';
  resp.on('data', function(chunk) {
    data += chunk;
  });
  resp.on('end', () => {
    exec.emit('data', data);
  });
}).on('error', (err) => {
  console.log('Error: ' + err.message);
});

修复说明

  • 使用encodeURIComponent单独编码查询参数值,确保特殊字符被正确转义
  • 移除多余的转义引号,让Prometheus正确识别查询表达式
  • 移除不必要的content-type头(GET请求参数在URL中,无需该头)

内容的提问来源于stack exchange,提问作者Gilles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:05:54