如何解决400 Bad Request问题

时间:2015-12-02 18:49:55

标签: php http arduino

我正在运行一个程序,使用对PHP页面的POST请求将有关泵运行时和安培数据的数据报告给服务器。该系统在几款Arduino Pro Minis上运行良好。我正在使用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);
  }
}

1 个答案:

答案 0 :(得分:1)

我猜想,有时候,inputData包含未经过正确编码的非转义字符,然后才能在POST正文中发送。

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

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