• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь POST запрос, регистрация платы esp32s[Node32s]

patriot_red_ru

New member
Пытаюсь зарегистрировать плату на специальном сервере.
Для этого использую POST запрос.
Пример как должен выглядеть запрос:
Код:
POST /auth/esp/register HTTP/1.1
Host: myhost
Content-Type: application/json
Cache-Control: no-cache

{"ESPIdentifier": "000:111:222:333:444"}

Код на Lua который я использую:
Код:
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "SSID";
const char* password =  "Pass_wifi";

const char* host = "myhost";
const int httpsPort = 443;

void setup() {
     
      Serial.begin(115200);
 
  Serial.print("connecting to ");
  Serial.println(ssid);
  Serial.println();
  WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  Serial.print("MAC: ");
  Serial.println(WiFi.macAddress());

      Serial.print("connecting to ");
      Serial.println(host);
      //Провека работы сервера
          if (!client.connect(host, httpsPort)) {
            Serial.println("connection failed");
          }
              else
          {
            Serial.println("OK");
          }
     
        while (WiFi.status() != WL_CONNECTED)
     
      delay(500);
      Serial.println("Waiting for connection...");





if(WiFi.status()== WL_CONNECTED){ //Проверка соединения wifi

      HTTPClient http;
      http.begin("ССЫЛКА НА РЕГИСРАЦИЮ");
      http.addHeader("Host", "myhost");
      http.addHeader("Content-Type", "application/json");
      http.writeToStream(&Serial);
      http.end();


      int httpResponseCode = http.POST("POST /auth/esp/register HTTP/1.1\r\n{\"ESPIdentifier\": \"000:123:265:312:484\"}");
    if (httpResponseCode > 0) { //Возвращаемое значение
        String payload = http.getString();
        Serial.println(httpResponseCode);
        Serial.println(payload);
      }
    else {
      Serial.println("Error on HTTP request");
    }
    http.end(); //Освобождение ресурсов
    }
else
   {
       
    Serial.print("Error in Wifi connection");
       
   }
     
      delay(30000); //Отправка запроса и проверка каждые 30 секунд
}

void loop() {


}
Сервер возвращает:
400 - не правильное оформление запроса

Было испытано большое количество вариантов оформления запросов...

Как правильно оформить запрос?
Что не так?
 

Алексей.

Active member
patriot_red_ru,
Одной и причин может быть проверка заголовка Host на сервере.
Может аутентификация не выполнена и сервер вместо 401-й ошибки возвращает 400-ю.

Не используя плату, на обычном ПК, не пробовали выполнять запрос?
 

patriot_red_ru

New member
patriot_red_ru,
Одной и причин может быть проверка заголовка Host на сервере.
Может аутентификация не выполнена и сервер вместо 401-й ошибки возвращает 400-ю.

Не используя плату, на обычном ПК, не пробовали выполнять запрос?
Пробовал, всё работает.
 

Алексей.

Active member
Вы при вызове http.POST передаете в пайлоаде (в теле сообщения) ещё и метод, зачем?
Клиента Вы уже инициализировали http.begin http.addHeader,
не понятно правда зачем ещё выполнили http.end
После инициализации выполняете явно метод POST, сервер скорее всего ожидает в пост-запросе джейсон, а Вы ему метод с урлом перед джейсоном шлете.
Передайте просто http.POST("{\"ESPIdentifier\": \"000:123:265:312:484\"}");

П.С.
Надеюсь вы не используете http.begin("ССЫЛКА НА РЕГИСРАЦИЮ") :)
а используете что то типа http.begin("https://myhost/auth/esp/register")
 
Последнее редактирование:

patriot_red_ru

New member
Вы при вызове http.POST передаете в пайлоаде (в теле сообщения) ещё и метод, зачем?
Клиента Вы уже инициализировали http.begin http.addHeader,
не понятно правда зачем ещё выполнили http.end
После инициализации выполняете явно метод POST, сервер скорее всего ожидает в пост-запросе джейсон, а Вы ему метод с урлом перед джейсоном шлете.
Передайте просто http.POST("{\"ESPIdentifier\": \"000:123:265:312:484\"}");

П.С.
Надеюсь вы не используете http.begin("ССЫЛКА НА РЕГИСРАЦИЮ") :)
а используете что то типа http.begin("https://myhost/auth/esp/register")

Я сделал по другому.

Код:
      HTTPClient http;
      http.begin("https://СЕРВАК/auth/esp/register");
      String postRequest =
      "POST /auth/esp/register HTTP/1.1 Host: myhost Content-Type: application/json {\"ESPIdentifier\": \"000:548:222:123:454\"}";
//так же пробовал
//"POST /auth/esp/register HTTP/1.1\r\nHost: myhost\r\nContent-Type: application/json\r\n{\"ESPIdentifier\": \"000:548:222:123:454\"}"\r\n;
//"POST /auth/esp/register HTTP/1.1\r\nHost: myhost\r\nContent-Type: application/json\r\nCache-Control: no-cache\r\n{\"ESPIdentifier\": \"000:548:222:123:454\"}"\r\n;
//"POST /auth/esp/register HTTP/1.1\r\nHost: myhost\r\nContent-Type: application/json\r\nCache-Control: no-cache\r\nESPIdentifier: 000:548:222:123:454"\r\n;
     int httpResponseCode = http.POST(postRequest);
Сервер возвращает:
Код:
415
{"Message":"The request contains an entity body but no Content-Type header. The inferred media type 'application/octet-stream' is not supported for this resource."}
Так же я попробовал через этот ресурс Послать POST/GET запрос - Инструментарий Web и JavaScript разработчика отправить POST запрос и вставить ИДЕпс: ИД прямо в хед как показано на рисунке.

И регистрация прошла успешно...

НО С ЕСПЕШКИ ТАК НЕ РАБОТАЕТ!
 

Вложения

Алексей.

Active member
patriot_red_ru, Завидное упорство,
в последнем примере Вы инициализируете клиента урлом, не добавляете никаких заголовков и в тело запроса по прежнему включаете и метод и иногда заголовки, их не должно быть в теле, сервер Вам однозначно ответил "запрос содержит сущность тела но нет заголовка Content-Type".
Непонятно почему вы не хотилте оставить первый пример, в котором был добавлен заголовок http.addHeader("Content-Type", "application/json") и убрать из тела название метода, оставив только джейсон.

В той ссылке которую вы использовали для проверки, ESPIdentifier в тело сообщения как
Код:
POST /auth/esp/register HTTP/1.1
Host: myhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://seriyps.ru/postget/
Content-Type: application/x-www-form-urlencoded
Content-Length: 108
Connection: keep-alive
Upgrade-Insecure-Requests: 1

Host=myhost&Content-Type=application0.000000json&Cache-Control=no-cache&ESPIdentifier=0000X0.0000000000003P-10221110X0.07FFC554145BFP-10222220X0.07FFC5541466P-10223330X0P+0444
это не то что вы хотели в начале
Код:
POST /auth/esp/register HTTP/1.1
Host: myhost
Content-Type: application/json
Cache-Control: no-cache

{"ESPIdentifier": "000:111:222:333:444"}
 
Последнее редактирование:

patriot_red_ru

New member
Непонятно почему вы не хотилте оставить первый пример, в котором был добавлен заголовок http.addHeader("Content-Type", "application/json") и убрать из тела название метода, оставив только джейсон.
Не могли бы вы показать, как я должен оформить запрос на Lua?
Просто я пробую как вы говорите, но возможно я вас не правильно понял.
 

Алексей.

Active member
patriot_red_ru, На луа я не умею :)
Я из Вашего примера выкинул проверку соединения в начале, выкинул добавления заголовка Host, клиент сам его добавляет и в теле сообщения оставил только джейсон.
Код:
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "****";
const char* password = "****";
void setup() {
  Serial.begin(115200);

  Serial.print("connecting to ");
  Serial.println(ssid);
  Serial.println();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  Serial.print("MAC: ");
  Serial.println(WiFi.macAddress());
  HTTPClient http;
  http.begin("http://192.168.4.1/auth/esp/register");
  http.addHeader("Content-Type", "application/json");
 
  int httpResponseCode = http.POST("{\"ESPIdentifier\": \"000:123:265:312:484\"}");
  if (httpResponseCode == 200) { //Возвращаемое значение
    String payload = http.getString();
    Serial.println(httpResponseCode);
    Serial.println(payload);
  } else {
    Serial.println("Error on HTTP request");
  }
  http.end(); //Освобождение ресурсов
}
void loop() {
}
Вот какой запрос был отправлен на сервер
Код:
POST /auth/esp/register HTTP/1.1
Host: 192.168.4.1
User-Agent: ESP32HTTPClient
Connection: close
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/json
Content-Length: 40

{"ESPIdentifier": "000:123:265:312:484"}
 

newnew

New member
patriot_red_ru, На луа я не умею :)
Я из Вашего примера выкинул проверку соединения в начале, выкинул добавления заголовка Host, клиент сам его добавляет и в теле сообщения оставил только джейсон.
Код:
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "****";
const char* password = "****";
void setup() {
  Serial.begin(115200);

  Serial.print("connecting to ");
  Serial.println(ssid);
  Serial.println();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  Serial.print("MAC: ");
  Serial.println(WiFi.macAddress());
  HTTPClient http;
  http.begin("http://192.168.4.1/auth/esp/register");
  http.addHeader("Content-Type", "application/json");
 
  int httpResponseCode = http.POST("{\"ESPIdentifier\": \"000:123:265:312:484\"}");
  if (httpResponseCode == 200) { //Возвращаемое значение
    String payload = http.getString();
    Serial.println(httpResponseCode);
    Serial.println(payload);
  } else {
    Serial.println("Error on HTTP request");
  }
  http.end(); //Освобождение ресурсов
}
void loop() {
}
Вот какой запрос был отправлен на сервер
Код:
POST /auth/esp/register HTTP/1.1
Host: 192.168.4.1
User-Agent: ESP32HTTPClient
Connection: close
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/json
Content-Length: 40

{"ESPIdentifier": "000:123:265:312:484"}
День добрый!
Извините если не в тему...
А запросы http.get() и http.post() можно использовать для обмена клиента на ESP и сервера?
Пробую следующую конструкцию:

do
cf={
web_url="http://mysite.ru/test.php",
var1=1,
var2=250,
var3=1
}

http.post(cf['web_url'],
'Content-Type: application/x-www-form-urlencoded\r\n',
'Term='..cf['var2']..'&Rele='..cf['var3']..'&ID='..cf['var1'],
function (http_code,http_data)
if(http_code < 0) then
print("HTTP request failed.")
else
print("Sent to the web OK")
--print (cf['web_url'])
end
end)
end

В ESPlorer получаю ответ:

Sent to the web OK.
Я так понимаю запрос на сервер отправлен?..
На страничке mysite.test.php содержащей
<?php

if(isset($_POST['ID'])&&!empty($_POST['ID'])){echo $_POST['ID']; }else{echo 'MISTAKE <br />\n';};
?>

печатается MISTAKE....

Не подскажете , что не так и как проверить уходит и приходит ли запрос...
 

Алексей.

Active member
newnew,
как то не понятно вы строите в запросе body
'Term='..cf['var2']..'&Rele='..cf['var3']..'&ID='..cf['var1']
печатается MISTAKE....
пых-пых пытается найти не пустой ID и не находит, посмотрите на сервере что в запросе приходит, может сразу станет понятно
вы сообщаете ему что тип контента application/x-www-form-urlencoded и он ожидает контент типа Term=250&Rele=1&ID=1

Не подскажете , что не так и как проверить уходит и приходит ли запрос...
если получаете "Sent to the web OK." значит запрос отправлен и получен ответ, правда совсем не понятно для чего вы это выводите на печать, чем не устроила печать кода ответа и данных ответа из примера не ясно, видимо так задумано :)
 

newnew

New member
newnew,
как то не понятно вы строите в запросе body
'Term='..cf['var2']..'&Rele='..cf['var3']..'&ID='..cf['var1']

пых-пых пытается найти не пустой ID и не находит, посмотрите на сервере что в запросе приходит, может сразу станет понятно
вы сообщаете ему что тип контента application/x-www-form-urlencoded и он ожидает контент типа Term=250&Rele=1&ID=1


если получаете "Sent to the web OK." значит запрос отправлен и получен ответ, правда совсем не понятно для чего вы это выводите на печать, чем не устроила печать кода ответа и данных ответа из примера не ясно, видимо так задумано :)
День добрый Алексей!
Спасибо за ответ.
На самом деле конструкция 'Term='..cf['var2']..'&Rele='..cf['var3']..'&ID='..cf['var1'] и есть в результате
Term=250&Rele=1&ID=1...
Использую YANDEX браузер, средства разработчика. Не вижу обмена с моим IP. В том то и дело.
Скрипт на страничке сайта работает. Принимает запросы из строки браузера вида http://mysite.ru/test.php?ID=1 . Уверенно печатает 1. Остаётся понять с кем обменивается POST запросом ESP шка...
 

Алексей.

Active member
Принимает запросы из строки браузера вида http://mysite.ru/test.php?ID=1 . Уверенно печатает 1
если уверенно печатает 1 то пых-пых этот ID берет из урла, а есп обменивается с тем же http://mysite.ru больше не с кем.
Можете попробовать на есп передать ID в урле.
 

newnew

New member
если уверенно печатает 1 то пых-пых этот ID берет из урла, а есп обменивается с тем же http://mysite.ru больше не с кем.
Можете попробовать на есп передать ID в урле.[/QU

Приветствую ещё раз!
Получил текст ответа от сервера... В ESPlorer.(Благодаря Вашей подсказке использовать код из примера..).
Ошибка 403....
Попробую разобраться с техподдержкой сайта.
Интересно, почему инструменты разработчика в браузере не выводят ответ сервера..
 

Алексей.

Active member
Серверу, который заворачивает запросы на пых-пых, похоже не нравится в запросе заголовок User-Agent, и он говорит 403 - типа вам туда нельзя, а у броузера User-Agent типа "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
 

newnew

New member
Серверу, который заворачивает запросы на пых-пых, похоже не нравится в запросе заголовок User-Agent, и он говорит 403 - типа вам туда нельзя, а у броузера User-Agent типа "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
Приветствую!
С сервером разобрались, тех поддержка сняла какие-то ограничения...В общем тупо предложили перейти на платный хостинг..(beget.tech).
Теперь ответ в ESPlorer :
200 12501�мя: Term Сообщение: 250 �мя: Rele Сообщение: 1 �мя: ID Сообщение: 1
http://mysite.ru/test.php/
Главное, как я понимаю, число 200 в начале строки. С абракадаброй разберусь позже.
Всё же остался главный вопрос- как извлечь данные из запроса..
Скрипт PHP по прежyему выдаёт MISTAKE. Массив $_POST[] по прежнему пустой..
 

Алексей.

Active member
newnew,
Вы бы локально сначала проверили бы, а потом и с хостером отношения выясняли.
На локальный сервер запросы бы по отправляли и посмотрели бы чем отличаются
Я стараюсь не пользоваться для отправки простых запросов всякими там инструментами, достаточно командной строки.
Bash:
#!/bin/bash
exec 7<>/dev/tcp/mysite.ru/80
echo -e "POST /test.php HTTP/1.1\r\nHost: mysite.ru\r\nContent-Type: application/x-www-form-urlencoded\r\nCache-Control: no-cache\r\nConnection: Close\r\nContent-Length: 20\r\n\r\nTerm=250&Rele=1&ID=1" >&7
cat <&7
отправил запрос скриптом и получил адекватный ответ
HTML:
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 09:28:54 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Length: 1
Connection: close
Content-Type: text/html; charset=UTF-8

1
 

newnew

New member
newnew,
Вы бы локально сначала проверили бы, а потом и с хостером отношения выясняли.
На локальный сервер запросы бы по отправляли и посмотрели бы чем отличаются
Я стараюсь не пользоваться для отправки простых запросов всякими там инструментами, достаточно командной строки.
Bash:
#!/bin/bash
exec 7<>/dev/tcp/mysite.ru/80
echo -e "POST /test.php HTTP/1.1\r\nHost: mysite.ru\r\nContent-Type: application/x-www-form-urlencoded\r\nCache-Control: no-cache\r\nConnection: Close\r\nContent-Length: 20\r\n\r\nTerm=250&Rele=1&ID=1" >&7
cat <&7
отправил запрос скриптом и получил адекватный ответ
HTML:
HTTP/1.1 200 OK
Date: Thu, 19 Apr 2018 09:28:54 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Length: 1
Connection: close
Content-Type: text/html; charset=UTF-8

1
Приветствую!
Спасибо за ответы и советы!
Вроде процесс пошёл. Просто первый проект с web...
бывает, что упрёшься во что нибудь и не видишь очевидных вещей...
Ну и пунктик-чё то никак к С душа не лежит.. В своё время ассемблером в основном пользовался.
Может(наверное точно) с С было бы проще..
Не возражаете, если в стену упрусь попрошу совета?
 

pvvx

Активный участник сообщества
Вот какой запрос был отправлен на сервер
Код:
POST /auth/esp/register HTTP/1.1
Host: 192.168.4.1
User-Agent: ESP32HTTPClient
Connection: close
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/json
Content-Length: 40

{"ESPIdentifier": "000:123:265:312:484"}
А где символы от 'chunked' и как совокупляются 'Content-Length: 40', 'chunked' и chunked + GZIP On по умолчанию у HTTP/1.1?
Специализированно заточенным сервером, адаптированным под данный неверный запрос?

C 'chunked' серверу ещё как-то понятно, т.к. правило гласит последовательный разбор директив, а последняя там 'Content-Length: 40', которая отменяет 'chunked'. Ответ придет загадочный – должен быть сжат GZIP или с 'chunked', т.к. указан HTTP/1.1.
Ответ ТС и получил в виде "абракадабры" :)
 
Последнее редактирование:
Сверху Снизу