html - 如何使用简单的 HTML 表单将指标发布到 InfluxDB?
问题描述
我正在尝试通过来自 HTML 表单的 POST 请求将 a0
或 a发送1
到我的 InfluxDB 实例中的数据库。我已经通过 成功完成了很多次curl
,但我无法使用简单的 HTML 表单使其工作。考虑以下 HTML 代码:
<!doctype html>
<!-- this file is called like http://my.influx.server/my_page_name.html -->
<html>
<head>
<title>my simple html/influx sender</title>
<meta charset="UTF-8"/>
</head>
<body>
<form action="http://my.influx.server:8086/write?db=db_name" method="post" enctype="text/plain">
<input name="data" type="hidden" value="my_measurement,tag_name=stuff value=1"/>
<input type="submit" value="insert 1"/>
</form>
<form action="http://my.influx.server:8086/write?db=db_name" method="post" enctype="text/plain">
<input name="data" type="hidden" value="my_measurement,tag_name=stuff value=0"/>
<input type="submit" value="insert 0"/>
</form>
</body>
</html>
curl
发送 a的命令1
如下:
curl -i -XPOST 'http://my.influx.server:8086/write?db=mydb' --data-binary 'my_measurement,tag_name=stuff value=1'
所以我尝试用 2 个按钮制作一个简单的 HTML 表单。上面的代码是我可以得到的最接近的代码,至少尝试处理“线路接口”语法,但是我收到一条错误消息或没有响应,而且我的 InfluxDB 中什么也没有。上面代码的错误信息是:
unable to parse 'data=my_measurement,tag_name=stuff value=1\r': invalid number
如果您仔细查看字符串的末尾,您会看到\r
明显添加了 a 并且我怀疑这会破坏数字解析(我前段时间有类似的东西),但至少这似乎试图评估该行全部。但是,我还没有找到删除或避免\r
. 有人知道如何实现这一目标吗?
此外,请考虑以下附加信息:
- 我希望它非常简单,只是一个可能包含一些 JavaScript 代码的小 HTML 文件,但我真的很想避免使用 PHP、jQuery 等。此外,正如您可能注意到的那样,我正在尝试习惯 HTML5,但这不应该是问题。
- 在这种情况下,我不需要每次按键的时间戳,因此我不传递时间戳,而是使用当前时间。这是通过省略时间戳来实现的,因此不包括 的字符串
\r
在语法上应该是正确的。 - 我还寻找了替代方案,但是只有使用 JSON 的想法,并且由于性能原因(我不希望在我的情况下),这似乎不再受支持。
- 该
curl
命令使用--data-binary
参数,但似乎我在 HTML 中没有这样的东西。我知道 binaryenctype
s likeapplication/x-binary
,但它们不起作用,因为它们对字符串进行 URL 编码,这不会通过语法检查。我发现唯一enctype
至少工作得足够接近的是text/plain
. <input>
如果相应的元素没有name
属性,我也知道没有发送表单数据。然后我注意到该curl
字符串是这样构建的my_measurement,tag_name=stuff value=1
,可能多个这样的行由 分隔\n
,这不像 POST 键值对a=1&b=2
(即没有键,那将是name
属性)。试图用name="my_measurement,tag_name"
andvalue="stuff value=1"
(类似于原始字符串)来欺骗它没有成功,我仍然无法弄清楚,哪个键是预期的。我尝试使用content
等query
并最终使用data
. 我之所以保留它,是因为在文档中他们谈论“数据”并且只要提供一个键,任何键都没有任何区别。我怀疑 InfluxDB 只是使用忽略名称的第一个 POST 变量,但我找不到任何明确的声明。- 我还尝试了几种不可见的
<input>
类型,例如 justhidden
或按样式隐藏的常规文本框。这没什么区别。可见元素也没有。 - 我也考虑过使用 AJAX,但我找不到关于没有键值内容的二进制 POST 的任何有用信息。我什至会处理目前仅适用于 Firefox 的页面,因此我不需要在不同的 AJAX 对象创建算法等之间切换(是的,我知道,jQuery 有帮助,但请参阅上面的第一点)。
编辑1:我试图重现错误curl
:
curl -i -XPOST 'http://my.influx.server:8086/write?db=home' --data-binary 'my_measurement,tag_name=stuff value=1\r'
这导致了错误消息:
unable to parse 'my_measurement,tag_name=stuff value=1\\r': invalid number
带标题:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Request-Id: ...
X-Influxdb-Build: OSS
X-Influxdb-Error: unable to parse 'my_measurement,tag_name=stuff value=1\r': invalid number
X-Influxdb-Version: 1.7.9
X-Request-Id: ...
Date: ...
Content-Length: 78
我总结:
\r
错误消息中的编码似乎不同(字符\
而r
不是实际的回车符),但在标题中它只是\r
,但是它对解析错误没有影响,所以这是可比较的。- 显然没有涉及到键名,所以这与我上面的尝试仍然不同。
编辑 2:我发现了如何从调用中显示请求标头curl
。命令是:
curl -v -XPOST 'http://my.influx.server:8086/write?db=db_name' --data-binary 'my_measurement,tag_name=stuff value=1'
该命令输出的相关部分是:
> POST /write?db=db_name HTTP/1.1
> Host: my.influx.server:8086
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 37
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 37 out of 37 bytes
< HTTP/1.1 204 No Content
< Content-Type: application/json
< Request-Id: ...
< X-Influxdb-Build: OSS
< X-Influxdb-Version: 1.7.9
< X-Request-Id: ...
< Date: Sat, 25 Jan 2020 10:54:11 GMT
我总结:
curl
with调用的请求的内容类型--binary-data
是application/x-www-form-urlencoded
。不幸的是,我无法看到实际的请求正文,所以我将使用一些 URL 编码的变体再试一次。但是,
my_measurement,tag_name=stuff value=1
请求标头中有 37 个字符,所以我假设没有像data
涉及的键名。目前,我收到与发布此问题之前相同的错误消息:unable to parse 'data=my_measurement%2Ctag_name%3Dstuff+value%3D1': missing fields
消失了,但我仍然无法在
\r
没有键名的情况下发送数据,并且由于 URL 编码,整个字符串无效。如何摆脱 URL 编码?
解决方案
最后,我找到了一个有效的 JavaScript 解决方案。这个 Mozilla 文档页面是没有密钥的 POST 表单的关键。我的 HTML 页面现在看起来像这样:
<!doctype html>
<!-- this file is called like http://my.influx.server/my_page_name.html -->
<html>
<head>
<title>my simple html/influx sender</title>
<meta charset="UTF-8"/>
</head>
<body>
<form id="form1">
<button>insert 1</button>
</form>
<form id="form0">
<button>insert 0</button>
</form>
<script>
function sendData(value)
{
const str = "my_measurement,tag_name=stuff value=" + value;
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(event) {
alert("Success");
});
xhr.addEventListener("error", function(event) {
alert("Error");
});
xhr.open("POST", "http://my.influx.server:8086/write?db=db_name");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(str);
}
const form0 = document.getElementById("form0");
const form1 = document.getElementById("form1");
form0.addEventListener("submit", function(event) {
event.preventDefault();
sendData(0);
});
form1.addEventListener("submit", function(event) {
event.preventDefault();
sendData(1);
});
</script>
</body>
</html>
注意精简的表单定义:不再有action
s、method
s 或enctype
s,因为它们是通过 JavaScript 设置的。此外,没有常规submit
元素,而是常规按钮,但我不知道是否需要。我稍后会调查。
主要部分位于表单下方的脚本标记中。一个函数sendData
准备一个XMLHttpRequest
对象来准备POST
一个准备好的字符串并调用它的send
方法。该函数用于submit
每个表单的事件中。此外,此函数为成功和失败的请求注册事件处理程序。
函数下方的行sendData
标识表单并在其submit
事件上注册事件侦听器。每个侦听器阻止其表单以常规方式提交并调用适当的sendData
调用,这将成功地将值插入 InfluxDB。
但是请注意,仍然不能保证检测到每个错误。我试图将一个字符串插入一个整数字段,但失败了,但我仍然收到“成功”警报。我稍后会对此进行调查。
所以总的来说,我认为这个问题已经充分解决了我的目的,我希望这可以帮助任何偶然发现它的人。
推荐阅读
- python-3.x - 合并熊猫数据框时出现KeyError:名称:TimeStamp,dtype:datetime64 [ns]
- pnpm - 如何以编程方式使用 pnpm / supi 安装软件包?
- flutter - 如何在一行内有多个(4)列(或类似的)与 ListView.builder 一起滚动
- docker - Docker 覆盖文件夹吃掉了 GB 的数据
- ember.js - Ember - Component property is not getting updated in template hbs
- listview - 如何使用 scroll_to_index 自动滚动 Flutter 中随机生成的列表项?
- watch - 如何在 saltstack 中查看特定文件并在文件发生任何更改时执行任何操作?
- dask - 直到 dask 2.2.0 read_parquet 过滤器参数似乎不再适用于 pyarrow 引擎
- python - Django - 如何记录错误并显示消息
- ruby-on-rails - 建立连接':数据库配置指定不存在的 mysql2 适配器 (ActiveRecord::AdapterNotFound)