【问题标题】:How to post metrics to InfluxDB with a simple HTML form?如何使用简单的 HTML 表单将指标发布到 InfluxDB?
【发布时间】:2020-08-12 12:05:56
【问题描述】:

我正在尝试通过来自 HTML 表单的 POST 请求将 01 发送到我的 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>

用于发送1curl 命令类似于:

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,我怀疑这会破坏数字解析(我前段时间有类似的东西),但至少这似乎尝试评估这条线。但是,我还没有找到删除或避免\r 的方法。 有人知道如何实现这一目标吗?

另外,请考虑以下附加信息:

  • 我希望它非常简单,只是一个可能包含一些 JavaScript 代码的小 HTML 文件,但我真的很想避免使用 PHP、jQuery 等。此外,您可能会注意到,我正在尝试习惯 HTML5,但这不应该是问题。
  • 在这种情况下,我不需要每次按键的时间戳,因此我不传递时间戳,而是使用当前时间。这是通过省略时间戳来实现的,因此不包括\r 的字符串在语法上应该是正确的。
  • 我也寻找了替代方案,但是只有使用 JSON 的想法,并且由于性能原因(我不希望在我的情况下),这似乎不再受支持。
  • curl 命令使用--data-binary 参数,但似乎我在 HTML 中没有这样的东西。我知道像application/x-binary 这样的二进制enctypes,但它们不起作用,因为它们对字符串进行URL 编码,这不会通过语法检查。我发现唯一至少工作得足够接近的enctypetext/plain
  • 如果相应的&lt;input&gt; 元素没有name 属性,我也知道没有发送表单数据。然后我注意到curl 字符串的构建类似于my_measurement,tag_name=stuff value=1,可能是多个这样的行,由\n 分隔,这不像a=1&amp;b=2 中的POST 键值对(即没有键,那将是name 属性)。试图用name="my_measurement,tag_name"value="stuff value=1" (类似于原始字符串)来欺骗它没有成功,我仍然无法弄清楚,应该使用哪个键。我尝试使用contentquery 等,最终使用data。我之所以保留它,是因为在文档中他们谈论“数据”并且只要提供一个键,任何键都没有任何区别。我怀疑 InfluxDB 只是使用忽略名称的第一个 POST 变量,但我找不到任何明确的声明。
  • 我还尝试了几种不可见的&lt;input&gt; 类型,例如hidden 或按样式隐藏的常规文本框。这没什么区别。可见元素也没有。
  • 我也考虑过使用 AJAX,但是我找不到关于没有键值内容的二进制 POST 的任何有用信息。我什至会处理一个只适用于 e 的页面。 G。对于现在的 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--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 编码?

【问题讨论】:

    标签: html forms post line-breaks influxdb


    【解决方案1】:

    最后,我找到了一个可行的 JavaScript 解决方案。 This Mozilla doc page 是没有键的 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>
    

    注意精简的表单定义:不再有 actions、methods 或 enctypes,因为它们是通过 JavaScript 设置的。此外,没有常规的submit 元素,而是常规按钮,但我不知道是否需要。我稍后会调查。

    主要部分在表单下方的脚本标记中。函数sendDataPOST 准备一个XMLHttpRequest 对象,并调用它的send 方法。该函数用于每个表单的submit 事件中。此外,此函数为成功和失败的请求注册事件处理程序。

    sendData 函数下方的行标识表单并在其submit 事件上注册事件侦听器。每个侦听器都会阻止其表单以常规方式提交,而是调用适当的 sendData 调用,这将成功地将值插入 InfluxDB。

    请注意,但仍不能保证检测到所有错误。我试图将一个字符串插入一个整数字段,但失败了,但我仍然收到“成功”警报。稍后我将对此进行调查。

    所以总的来说,我认为这个问题已经完全解决了我的目的,我希望这可以帮助任何遇到它的人。

    【讨论】:

      【解决方案2】:

      这是一篇非常有用的帖子,我在 Sigfox 后端和回调中遇到了这个问题。

      如果您在 URL 末尾添加 & 并使用内容类型 text/plain,则 \r\n 问题得到解决。

      【讨论】:

      • 感谢您的反馈。换行问题只是一个可疑点,对我来说没有任何意义。事实证明,我的实际问题是键/值问题。但是“URL&”点仍然很有趣。你能告诉我,你在哪里找到了暗示吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多