【问题标题】:POST Request with WiFiNina Library on Arduino Uno Wifi Rev 2在 Arduino Uno Wifi Rev 2 上使用 WiFiNina 库发布请求
【发布时间】:2020-01-27 21:02:01
【问题描述】:

我正在尝试为 Arduino Uno WiFi Rev2 板编写一些代码。具体来说,我想使用 POST HTTP 请求将一些数据发送到我编写的 API 端点。我已经用 Postman 测试了这个端点,它工作正常。但是,当我尝试使用 WiFiNina 库 (https://www.arduino.cc/en/Reference/WiFiNINA) 发布我的数据时,请求永远不会到达我的端点。

我的 Arduino 草图包含两个文件。第一个是我的“主”文件,它作为我的代码的入口点并处理我的代码的大部分功能。在这个文件中,我按照 Arduino 文档中的说明设置了 WiFiClient:

#define URL "myappdomain.azurewebsites.net"
...
WiFiClient client;
int status = WL_IDLE_STATUS;
...
void setup(){
...
status = WiFi.begin(WifiSSID, WifiPassword);

  while (WiFi.status() != WL_CONNECTED) {  //Wait for the WiFI connection completion
    delay(500);
    Serial.println("Waiting for connection");
  }
...
}
...

void loop(){
...
String requestBody = 
    "{\n    \"clientReadings\": {\n        \"sensorA\": [],\n        \"sensorB\": []\n    },\n    \"deviceId\": 1,\n    \"millilitersConsumed\" : 999\n}";

//send the request
postData(requestBody);
...
}

在我的第二个文件中,这是处理此 API 请求的代码部分:

void postData(String body){
  if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status

     if (client.connect(URL, 80)){
        client.println("POST /api/PGWC HTTP/1.1"); 
        client.print("Host: ");
        client.println(URL);
        client.println("Content-type: application/json");
        client.println("Accept: */*");
        client.println("Cache-Control: no-cache");
        client.print("Host: ");
        client.println(URL);
        client.println("Accept-Encoding: gzip, deflate");
        client.print("Content-Length: ");
        client.println(body.length());
        client.println("Connection: close");
        client.println();
        client.println(body);
     }else{
      Serial.println("Error connecting to server");
     }
  }
}

我根据我在网上找到的 WiFiNina 库的示例和文档构建了这个请求。 (这里有一个例子:https://www.arduino.cc/en/Reference/WiFiNINAClient)。标头信息和正文基于我通过 Postman 发送的请求,因此我相信我的请求内容是准确的。我相信我能够通过“client.connect”行连接到服务器,因为我从未看到错误消息打印到串行监视器,但我看到串行监视器显示“Serial.println”语句的内容我放在我的“client.println”语句之前。但是,托管 API 终结点的 Azure Function App 没有显示 API 终结点已被命中的迹象。当我使用 Postman 发送相同的数据时,函数应用会很好地记录连接。

当我尝试从 postData 函数中将正文、URL 和 body.length() 的内容打印到串行监视器时,一切都按预期显示。此外,我在“连接:关闭”行尝试了不同的选项,但无济于事。

作为参考,下面是 Postman 在成功到达 API 端点时告诉我它正在发送的内容。我也尝试过 443 端口。它在 Postman 中运行良好,但在 Arduino 中又不行。

Host: myappdomain.azurewebsites.net:80
Content-Type: application/json
User-Agent: PostmanRuntime/7.17.1
Accept: */*
Cache-Control: no-cache
Postman-Token: [some UUID, some other UUID]
Host: myappdomain.azurewebsites.net:80
Accept-Encoding: gzip, deflate
Content-Length: 130
Connection: keep-alive
cache-control: no-cache

{
    "clientReadings": {
        "sensorA": [],
        "sensorB": []
    },
    "deviceId": 1,
    "millilitersConsumed" : 123
}```

(I've changed the domain for this post, so this request won't work if you try to plug it into Postman because myappdomain.azurewebsites.net is not my real domain)

【问题讨论】:

  • 服务器是否接受端口 80 上的连接?对于端口 443,您是否使用了 connectSSL()?删除重复的主机头
  • @Juraj - 它接受端口 80 上的连接。我用 connectSSL 尝试了端口 443。我无法让 connectSSL 成功,但是,当我返回尝试删除重复主机头的端口 80 时,它开始工作了!我可以发誓我以前尝试过,但我想不会。无论如何,谢谢你的帮助。它现在似乎正在工作
  • 我有同样的问题,无法让它工作。我有一个用 Vapor 构建的快速服务器并使用客户端 Rested(就像邮递员)一切都很好,但是使用 arduino 它失败并出现此错误 {"reason":"Unprocessable Entity","error":true} 我也在做同样的事情你正在做的事情;也可以作为参考,arduino 的 GET 工作正常

标签: http post arduino arduino-uno-wifi


【解决方案1】:

编辑:想通了。

原来是wifi.println("Content-Length: " + body.length());

wifi.println("Content-Length: " + String(body.length()));不一样

body length var 需要被包裹成一个字符串,然后它就可以正常工作了

让我感到困惑的是看到 OP 把它写成

wifi.print("Content-Length: ");
wifi.println(body.length());

我不认为它需要被包装成一个字符串,但我猜当连接字符串时它会有所不同。

我也很好奇我需要这个标头开始(REST 应用程序不需要它工作)并具有正确的正文值,使用 200 之类的东西会导致连接挂起(但在 REST 应用程序设置上像 200 这样通用的东西也可以正常工作)

END EDIT ...留下原始内容以供参考

我也在尝试解决这个问题,所以这是一个扩展评论而不是答案。

当我使用像邮递员(休息)这样的应用程序时,我得到 200 个响应,但从 arduino uno wifi rev2 失败并显示HTTP/1.1 422 Unprocessable Entity {"reason":"Unprocessable Entity","error":true}

我的 json 只是 String body = "{\n \"value\": 500\n}";

if (wifi.connect(serverAddress, port)) {内部

我打电话

void postData(String body) {
// send HTTP request header
wifi.println("POST /gardener/Douglas/George/water HTTP/1.1");
wifi.println("Host: " + String(serverAddress));
wifi.println("Content-Type: application/json");
wifi.println("Accept: */*");
wifi.println("Cache-Control: no-cache");
wifi.println("Accept-Encoding: gzip, deflate");
wifi.println("Accept-Language: en-us");
wifi.println("Content-Length: " + body.length()); //ANSWER: body.length() needs to be wrapped as a string, see above
wifi.println("Connection: close");
wifi.println(); // end HTTP request header
wifi.println(body);
}

fwiw 获取请求工作正常

void getHello() {
wifi.println("GET /hello HTTP/1.1");
wifi.println("Host: " + String(serverAddress));
wifi.println("Connection: close");
wifi.println(); // end HTTP request header
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    相关资源
    最近更新 更多