server.args() ESP8266 Arduino

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

当我使用POSTMAN工具进行POST请求,内容类型为text/plain时,请求体的内容将显示在串行监视器中。
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()时出了些问题。我的理解是,无论contentType是text/plain还是x-www-form-urlencoded,server.args()都应该提供POST中使用的主体内容。

我是否做错了什么,或者说我们不能从POST请求中获取body数据吗?

2个回答

9

ESP8266WebServer的实现中有一些需要注意的地方。我发现正文显示在

server.arg("plain")

但仅当类找不到任何键值对时才会这样做。ESP8266WebServer将查找“=”,只有在找不到“=”时才会将正文放入“plain”参数中。

此参数将包含完整的正文,因此您需要自行解析JSON。我发现ArduinoJson是一个非常易于使用的库。

简短示例:

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

在旁边提一句,如果您正在使用类似POSTMAN的工具进行测试,请不要忘记设置“Content-length”。如果与此标题值不对应,ESP8266WebServer将把您的正文视为空(或长度不同)。希望这回答了您的问题。

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);
});

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接