1. 环境准备
-
使用 postJson 工具
可以先了解如下知识:
-
HTTP 请求方式 GET 和 post 区别
URL 描述一个网络上的资源,而 GET,POST,PUT,DELETE 就对应着对这个资源的 查,改,增,删 4 个操作。
- GET 用于从服务器上获取数据信息
- POST 用于向服务器传送数据信息
- POST 请求方式 ---- 主要特点是把请求数据放在 body
- x-www-form-urlencoded:就是 application/x-www-from-urlencoded,会将表单内的数据转换为键值对
- raw: 可以通过 raw 进行传输 txt,json xml,html 的数据
- form-data:对应于 Content-Type 的 multipart/form-data 类型,既可以发送键值对也可以进行文件参数传递。
- binary:用来发送文件内容请求。
- POST 请求方式 ---- 主要特点是把请求数据放在 body
-
响应状态码类别
- 1xx 指示信息 – 表示请求已接收,继续处理
- 2xx 成功 – 表示请求已被成功接收、理解、接受
- 3xx 重定向 – 信息不完整需要进一步补充
- 4xx 客户端错误 – 请求有语法错误或请求无法实现
- 5xx 服务器端错误 – 服务器未能实现合法的请求
常用看到的状态码:
- 200 - 请求成功,已经正常处理完毕
- 404 - 客户端请求的 URL 在服务端不存在
- 502 - 服务器内部错误,无法完成请求
对于详细的文档说明:
2. ESP32 demo 验证
使用 esp-idf/examples/protocols/esp_http_client 下的例程来进行测试。
void app_main(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
ESP_LOGI(TAG, "Connected to AP, begin http example");
xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL);
}
static void http_test_task(void *pvParameters)
{
http_rest_with_url();
ESP_LOGI(TAG, "Finish http example");
vTaskDelete(NULL);
}
static void http_rest_with_url(void)
{
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
/**
* NOTE: All the configuration parameters for http_client must be spefied either in URL or as host and path parameters.
* If host and path parameters are not set, query parameter will be ignored. In such cases,
* query parameter should be specified in URL.
*
* If URL as well as host and path parameters are specified, values of host and path will be considered.
*/
esp_http_client_config_t config = {
.host = "httpbin.org",
.path = "/get",
// .query = "esp",
.event_handler = _http_event_handler,
.user_data = local_response_buffer, // Pass address of local buffer to get response
.disable_auto_redirect = true,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
// GET
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
}
ESP_LOG_BUFFER_HEX(TAG, local_response_buffer, strlen(local_response_buffer));
char *buffer = malloc(MAX_HTTP_RECV_BUFFER + 1);
if (buffer == NULL) {
ESP_LOGE(TAG, "Cannot malloc http receive buffer");
return;
}
if ((err = esp_http_client_open(client, 0)) != ESP_OK) {
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
free(buffer);
return;
}
int content_length = esp_http_client_fetch_headers(client);
int total_read_len = 0, read_len;
if (total_read_len < content_length && content_length <= MAX_HTTP_RECV_BUFFER) {
read_len = esp_http_client_read(client, buffer, content_length);
if (read_len <= 0) {
ESP_LOGE(TAG, "Error read data");
}
buffer[read_len] = 0;
ESP_LOGI(TAG, "read_len = %d,data: %.*s", read_len,read_len,buffer);
}
// POST
const char *post_data = "{\"field1\":\"value1\"}";
esp_http_client_set_url(client, "http://httpbin.org/post");
esp_http_client_set_method(client, HTTP_METHOD_POST);
esp_http_client_set_header(client, "Content-Type", "application/json");
esp_http_client_set_post_field(client, post_data, strlen(post_data));
err = esp_http_client_perform(client);
if (err == ESP_OK) {
char *buffer1 = malloc(MAX_HTTP_RECV_BUFFER + 1);
esp_http_client_get_post_field(client, &buffer1);
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d, buffer1: %s",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client), buffer1);
} else {
ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
}
可以通过获取到 GET 请求数据格式,打印出来。如下截图所示:
3. 注意事项:
-
网址 URL 重定向
这是因为
esp
无法像Web
浏览器一样自动重定向 URL。
最可能的解释是Web
服务器没有发送.bin
文件,而是发送了其他内容。应用程序映像.bin
文件的第一个字节应为0xE9
。该错误表明该文件的第一个字符0x3C
是ASCII “<”
,并暗示服务器正在发送 HTML 页面而不是.bin
文件。您可以尝试将相同的 URL 放入命令行上的 curl 等工具中并以这种方式下载,看看
.bin
文件是否已下载或是否为其他内容(如错误页面、登录页面或重定向页面))。
-
如果一直没有办法成功获取到 http server 的正确响应。此时就需要具体通过 postman 或者 postJson 工具具体查看一下
set_header
设置头组装的是否正确,是否是按照服务器端的标准头格式发送的数据。
如果还是查不出问题所在,就需要通过抓包卡(wireshark 等)来具体查看 http 包,查看具体是设备端没有发送正确的格式还是服务端没有响应。