我试图通过来自HTML的POST请求将0或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命令的1如下所示:
curl -i -XPOST 'http://my.influx.server:8086/write?db=mydb' --data-binary 'my_measurement,tag_name=stuff value=1'所以我试着用两个按钮制作一个简单的HTML表单。上面的代码是我能找到的最接近的代码,至少我试图处理“行接口”语法,但是我要么收到错误消息,要么没有响应,而且我的InfluxDB中没有任何内容。上面代码中的错误消息是:
unable to parse 'data=my_measurement,tag_name=stuff value=1\r': invalid number如果仔细查看字符串的末尾,就会看到一个明显被添加的\r,我怀疑这会破坏数字解析(不久前我也有类似的情况),但至少这似乎是在试图计算行。但是,我还没有找到一种方法来删除或避免\r。有一个如何实现这一目标的想法?
此外,请考虑下列补充资料:
\r的字符串在语法上应该是正确的。curl命令使用--data-binary参数,但在HTML中似乎没有类似的内容。我知道二进制enctype是像application/x-binary那样的,但是它们不起作用,因为它们对字符串进行了URL编码,这不会通过语法检查。我发现的唯一一个工作至少足够接近的enctype是text/plain。<input>元素没有name属性,我还知道表单数据没有被发送。然后,我注意到curl字符串的构建类似于my_measurement,tag_name=stuff value=1,可能是由\n分隔的多个这样的行,这不像在a=1&b=2中那样类似于POST键值对(即没有键,那就是name属性)。试图用name="my_measurement,tag_name"和value="stuff value=1" (类似于原始字符串)来欺骗它是不成功的,我仍然无法弄清楚,需要哪个键。我尝试过使用content、query等,最后使用了data。我当时保留了这个,因为在文档中,他们谈论的是“数据”,只要提供了一个键,任何键都不会有任何不同。我怀疑InfluxDB只是使用了第一个POST变量,忽略了这个名称,但是我找不到任何明确的声明。<input>类型,比如hidden或常规的textbox。这没什么区别。可见元素也没有。编辑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。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-编码?发布于 2020-02-03 13:05:49
最后,我找到了一个与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>请注意简化的表单定义:不再存在actions、methods或enctypes,因为它们是通过JavaScript设置的。另外,这里没有常规的submit元素,相反,它是一个普通的按钮,但是我不知道是否需要这样做。稍后我会调查的。
主要部分在表单下面的脚本标记中。函数sendData准备用于POST准备的字符串的XMLHttpRequest对象,并调用其send方法。此函数用于每个窗体的submit事件。此外,此函数为成功和失败的请求注册事件处理程序。
sendData函数下面的行标识表单并在其submit事件上注册事件侦听器。每个侦听器阻止其表单以常规方式提交,而是调用适当的sendData调用,这将成功地将值插入到InfluxDB中。
但是要注意,仍然没有任何保证可以检测到每一个错误。我试图将一个字符串插入一个整数字段,但失败了,但我仍然得到了“成功”-alert。我以后会调查的。
因此,总的来说,我认为这个问题在我看来已经足够解决了,我希望这能帮助人们发现这个问题。
发布于 2020-08-12 04:05:56
这是一篇非常有用的文章,我在Sigfox后端和回调中遇到了这个问题。
如果将&放在URL的末尾,并使用内容类型text/平原,则\r\n问题将得到解决。
https://stackoverflow.com/questions/59887801
复制相似问题