6

我将 ESP8266 与 Arduino IDE 一起使用,并在端口 200 设置了一个服务器。IP 也定义为与 192.168.1.100 相同。

ESP8266WebServer server(200);
IPAddress ip(192, 168, 1, 100); //Node static IP
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);


server.on("/parseIFTTT", parseIFTTT); 


void parseIFTTT() {

  String message;
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  Serial.println(message);
  Serial.println(server.argName(0));
  Serial.println(server.arg(0));
  server.send(200, "text/plain", "Success  " + message);
}

完成以将 parseIFTTT 请求路由到此 parseIFTTT() 方法。

我已经完成了端口转发并使用duckdns 从外部访问该服务器。这是我的duckdns地址

http://xxxxxx.duckdns.org:200/parseIFTTT

当我使用内容类型为 text/plain 的 POSTMAN 工具进行 POST 时,正文内容在串行监视器中显示为

plain
--body contents--

但是,当 IFTTT 发出相同的请求时,串行监视器只显示空的内容。最初我觉得问题出在 IFTTT 上。但这不是问题,因为当我在 arduino 中使用 WiFiWebServer 示例时,使用以下代码

  String req = client.readString();
  Serial.println(req);
  client.flush();

我将 IFTTT 的数据视为:

POST /parseIFTTT HTTP/1.1
Content-type: text/plain
host: xxxxxx.duckdns.org:200
content-length: 27
x-newrelic-id: XAMGV15QGwQJVllRDgQ=
x-newrelic-transaction: PxQFA1NbAQQJVwJWA1dSB0YdUFIOFQZOEgEPVA5ZBFYGXAwECFgFAFcUG0MHUwoLBAcDAxVs
Connection: close

{"value":"test data from IFTTT"}

所以我相信我在 server.args() 上做错了。我的印象是 server.args() 应该给出 POST 中使用的正文内容,无论 contentType 是 text/plain 还是 x-www-form-urlencoded。

我做错了什么或者 server.args() 我们不能从 POST 请求中获取正文数据吗?

4

2 回答 2

8

ESP8266WebServer 的实现中有一些“陷阱”。我发现尸体出现在

server.arg("plain")

但前提是类找不到任何键值对。ESP8266WebServer 将寻找一个“=”,只有当它找不到一个时,它才会将主体放在“普通”arg 中。

此 arg 将包含整个正文,因此您必须自己解析 JSON。我发现ArduinoJson是一个非常易于使用的库。

简短的例子:

void handleRequest() {  
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(server.arg("plain"));
  root.printTo(Serial);
}

在旁注上。如果您正在使用类似 POSTMAN 的工具进行测试,请不要忘记设置“内容长度”。如果与此标头值不对应,ESP8266WebServer 会将您的正文视为空(或长度不同)。

希望这能回答你的问题。

于 2017-02-02T08:26:42.650 回答
0

感谢“如何使用 ESP8266WebServer 获取 IP 客户端”的代码解决方案是:

// HTTP Request Path, IRIA Entry Form
server.on("/", [](){                       
  // As sending the form as a response to the client
  server.send(200, "text/html",login_CASA);
  String addy = server.client().remoteIP().toString();
  Serial.println(addy);
});
于 2022-01-10T01:14:33.740 回答