【问题标题】:How do I troubleshoot a 400 Bad Request如何对 400 错误请求进行故障排除
【发布时间】:2026-02-09 19:50:01
【问题描述】:

我正在运行一个程序,该程序使用对 PHP 页面的 POST 请求向服务器报告有关泵运行时和放大器的数据。该系统在几个 Arduino Pro Mini 上运行良好。我正在使用 328 和 Arduino Uno 引导加载程序构建的板上对其进行测试,在 4 个不同的 POST 请求中,两个有效,两个失败。

我认为这是由于 Arduino 的 POST 请求形成不当造成的,但我无法验证这一点,因为 Arduino Serial.prints 正确的字符串。如果我手动对字符串进行硬编码,它也可以工作。

我是这样形成数据的:

byte runtime = analogRead(A3); // generates random data
float amps = analogRead(A2) / 100;
char cruntime[4]; // create char array for runtime
char camps[5];
dtostrf(runtime, 4, 0, cruntime);
dtostrf(amps, 2, 1, camps);
String sruntime = String(cruntime);
sruntime.trim();
String samps = String(camps);
samps.trim();
String cwpdata = "serial=test&runtime=" + sruntime + "&amps=" + samps; // posted to server

我检查了我的服务器是否有错误,但找不到这些记录。无论如何我可以看到每次发布的内容,以便我可以看到请求没有正确形成的地方吗?

这是 Arduino 中发布数据的代码:

void postData(String inputData, String filename) {
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("POST /dev/telemetry/test/" + filename + ".php HTTP/1.1");
    client.println("Host: www.SERVER.com"); // changed for privacy
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: "); 
    client.println(inputData.length()); 
    Serial.println(inputData);
    Serial.print("Data Length: ");
    Serial.println(inputData.length());
    client.println("Connection: close");
    client.println(); 
    client.println(inputData);
    client.println();
  } // close if client

  wdt_reset();
  unsigned long startMillis = millis();
  unsigned long endMillis = startMillis + timeout;
  while(client.connected() && (millis() < endMillis)) {
    wdt_reset();
    while(client.available()) {
      char ch = client.read();
      Serial.print(ch);
      wdt_reset();
    } 
  }
  // if the server's disconnected, stop the client:
  Serial.println();
  client.stop();
  int memory = freeMemory();
  if (memory < 125) {
    delay(15000);
  }
}

【问题讨论】:

  • 你的服务器上应该有一个error.log。
  • 我查看了我找到的所有错误日志,但没有看到。我再看看。
  • 我再次查看了该文件夹和上面文件夹中的所有错误日志,但一无所获。我查看了原始服务器日志,没有出现 400。
  • 您的代码缺少重要部分:您如何将数据发送到服务器?
  • @MikeCAT 我添加了代码。

标签: php http arduino


【解决方案1】:

我会大胆猜测,有时,您的 inputData 包含未转义的字符,这些字符在发送到 POST 正文之前未正确编码。

"serial=test&amp;runtime=" + sruntime + "&amp;amps=" + samps 内,如果sruntimesamps 包含未转义的字符,则很可能会导致服务器端解析失败。 Serial.println(inputData) 中是否隐藏了任何可能被忽略的“不可打印”控制字节?

顺便说一句,“安全”字符是 A-Z、a-z、0-9、破折号、下划线、点、波浪号和加号(表示空格)。在发送之前,其他所有内容都必须是percent-encoded。如果数据恰好是 Unicode,它会得到一个 little hairier

【讨论】:

  • 我认为你可能是对的。有一次我在 inputData 中发现了一个空格,这就是我添加 trim() 命令的原因,但这也并不总是有效。这让我对 C 感到厌烦,因为将数据更改为字符串非常复杂,而且各种事情都发生在幕后。