отправка get запроса
- Войдите на сайт для отправки комментариев
Втр, 27/07/2021 - 21:00
первый раз вообще работаю с вайфаем , подключил себе бесплатный ddns . Для обновления айпи , предлагает сделать следующее :

Попытался понять как делать этот запрос , у меня вышло следующее :
if (client.connect(ip_update_host,80)) { }
client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=токен[цензура]&myip=");
client.println ("HTTP/1.1");
client.println ("Host: dynupdate.alviy.com");
client.println();
client.println();
, в ответ получаю :
Response of DDNS-Server: <html> <head><title>400 Bad Request</title></head> <body> <center><h1>400 Bad Request</h1></center> <hr><center>cloudflare</center> </body> </html>
к слову , так и не понял ,зачем нужно делить запрос на части , куда проще же отправить все в одном , да и сервер не запутается ,собирая его по кусочкам.
буду благодарен за конструктив , а так же материалы, которые мне следовало бы изучить.
Открывать esp8266 в интернет, да еще и под доменом - плохая затея. Будет падать от сканеров постоянно.
Ну и http запросы делаются библиотекой, а не вручную.
а что мне еще делать? мне нужно как-то из вне отправить именно на мою esp пакет, так вот у нее постоянно меняется айпи , а ddns сервер знает какой он .Его роль отправить пакет моей esp , вне зависимости от ее айпи, который я могу не знать. я это делаю через библиотеки <WiFiClient.h> <ESP8266WiFi.h>
Прям в голый сокет на 80-й порт валите текст? HTTP тоись устраиваете врукопашную? А GET должен по HTTPS производится.
Да и сам cloudfire побрить может, кстати, если IP не понравится.
Ну, на самом-то деле уже неплохо. Только client должен быть clientSecure из WifiSecureClient.h, и порт 443. А cloudflare он такой, да.
не могу нигде найти WifiSecureClient.h , можете дать ссылку? после смены порта , выдал это :
если честно , вообще не понимаю , зачем указывать порт при подключении, разве этот порт тебе выдает не провайдер? NAT , он тебе дает внутренний порт , а при подключении , вообще его меняет на свой. А если и нужно , то зачем и как мне узнать какой? 80 порт я увидел в примере другого человека , вот и написал. Максимально далек от этой темы...
Cloudflare всё правильно написал, вы попытались отправить незашифрованный запрос на порт, который этого не ожидает. Кстати, CF также порежет довольно много сканеров, что в данном случае есть хорошо, хоть лично я и не особо люблю CF.
Библиотека WifiSecureClient (или WifiClientSecure, не помню) входит в поставку, и там даже есть пример https запроса, прямо в вашей IDE у вас на компе.
если честно , вообще не понимаю , зачем указывать порт при подключении, разве этот порт тебе выдает не провайдер? NAT , он тебе дает внутренний порт , а при подключении , вообще его меняет на свой. А если и нужно , то зачем и как мне узнать какой? 80 порт я увидел в примере другого человека , вот и написал. Максимально далек от этой темы...
Вы "подключаетесь" к комбинации ip-адрес + порт. Порт нужен потому, что на одном адресе может быть несколько служб, например, на 80м http-сервер, на 443м https сервер, на 27015 игровой сервер (все три запущены на одном компьютере, ip одинаковый), и порт нужен для того, чтобы определить, какой из трёх серверов получит ваш запрос.
С вашей стороны тоже присутствует ip+port, за натом или без, в случае клиента неважно, tcp-соединение устанавливается между двумя ip/port-ами. Ваш клиентский ip+port (ардуина esp) обращается к серверному ip+port-у (сервер dyndns), просто библиотека от вас это прячет.
Если максимально далеки - придётся подтянуться, без этих базовых знаний ничего не получится, только глумиться дальше будут.
спасибо , разбираюсь по тихоньку. Переписал на HTTPS , удалось подключится , вот только в ответ получил
внизу написано про cloudflare , я так понимаю , что это его рук дело ,а не в неправильном запросе?
скину код целиком ,На всякий случай :
#include <ESP8266WiFi.h> // Библиотека для создания Wi-Fi подключения (клиент или точка доступа) #include <WiFiClientSecure.h> // Библиотека для связи с сетевыми хостами (локальными и интернет) #include <ESP8266WebServer.h> // Библиотека для поднятия веб-сервера ww const char* ssid = "a1a"; // Указываем имя WiFi-сети, к которой будет подключаться ESP8266 const char* password = "30"; // Указываем пароль для подключения к WiFi-сети const char* ip_update_host = "dynupdate.alviy.com"; // Указываем хост (адрес сайта) службы DynDNS const char fingerprint[] PROGMEM = "61 58 CC 6C C3 B8 00 96 DB 17 88 52 8A 4D 5E 11 0E DC DF 53"; ESP8266WebServer server(10200); // Создаём объект для работы с нашим веб-сервером, указав номер порта, по которому он будет доступен в WWW WiFiClientSecure client; // Создаём объект для работы с удалёнными хостами void setup(void){ Serial.begin(9600); // Инициализируем вывод данных на серийный порт со скоростью 9600 бод WiFi.begin(ssid, password); // Соединяемся с WiFi-сетью while (WiFi.status() != WL_CONNECTED) // Пока соединение не установено delay(500); // делаем задержку в пол секунды, пока соединение не установится Serial.println("WiFi connected"); Serial.print("Connected to "); Serial.println(ssid);// Выводим сообщение о том, что устройство соединилось с WiFi-сетью server.begin(); // Инициализируем работу веб-сервера server.on("/", root); // Сообщаем о том, что при обращении к корневой директории нашего веб-сервера должна вызываться функция root Serial.println("HTTP server started"); // Выводим на монитор серийного порта сообщение о том, что веб-сервер запущен Serial.print("Local IP: "); // Выводим на монитор серийного порта сообщение о том, что сейчас будем выводить локальный IP Serial.println(WiFi.localIP()); // Выводим локальный IP-адрес ESP8266 Serial.print("MAC-address: "); // Выводим на монитор серийного порта сообщение о том, что сейчас будем выводить MAC-адрес ESP8266 Serial.println(WiFi.macAddress()); // Выводим MAC-адрес ESP8266 client.setFingerprint(fingerprint) ; ip_update(); // Вызываем функцию, обновляющую IP маршрутизатора (роутера) в службе динамических DNS } void loop(void){ } void ip_update(){ // Функция, обновляющая IP маршрутизатора (роутера) в службе динамических DNS while (!client.connect(ip_update_host,443)) { Serial.println ("connection to ddns error"); } Serial.println ("conection to ddns successfull!"); Serial.println (" GET request senting..."); client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=2f6памыпррыу71&myip="); //отправка запроса на обновление айпи в ddns client.println ("HTTPS/1.1"); client.println ("Host: dynupdate.alviy.com"); client.println ("Connection: close"); client.println(); client.println(); delay(200); // Задержка в 0.2 сек., чтобы дать удалённому серверу возможность обработать и отправить ответ на наш запрос Serial.println("\nResponse of DDNS-Server:"); // Шлём в монитор серийного порта сообщение о том, что далее будет выводиться ответ от сервера службы DynDNS while (client.available()) { // Пока сервер на связи char a = client.read(); // считываем его ответ по одному символу Serial.print(a); // и выводим на монитор серийного порта } } void root(){ // Функция,вызывающаяся при обращении клиента к корневой дирректории нашего веб-сервера server.send(200, "text/html","<h1>Web-server ESP8266</h1>"); // Сервер отправляет клиенту информацию о том, что } // 200 - запрос успешно обработан // text/html - ответ на запрос предоставляется в формате HTML // третий параметр (<h1>Web-server ESP8266</h1>) содержит текст ответа в формате HTMLчто-то немного поправил, теперь получаю :
403я ошибка - это ты обратился к серверу туда, куда доступ не всем разрешён. Проверь адрес и/или токен.
токен скопировал тот , что мне дал ddns , все правильно.
В браузере у себя на пк пробовал по сформированному url заходить? Что получается?
client.println ("HTTPS/1.1");удалите, нету такого заголовка, не нужно такую херню слать серверу
client.println ("Connection: close");это не обязательно отправлять в данном случае, всё равно же сами закрываете соединение, но это пофигу, не страшно, можно и отправлять
с браузера удалось зайти.
переписал , как мне и сказали , удалив лишнее :
client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=а87478141&myip="); client.println ("Host: dynupdate.alviy.com"); client.println(); client.println();результат не изменился - 403.
все же не в этом дело , ничего не изменилось .
client.println("GET /token/update?hostname=esp8266-x.dynnamn.ru&token=2427507310535729057891&myip="); client.println ("Host: dynupdate.alviy.com"); client.println(); client.println();ответ : 403 .
ннууу
откройте новую вкладку браузера, нажмите ctrl+shift+i, откроются devtools
скопипастьте в эту вкладку ваш урл https://dynupdate.alviy.com/token/update?hostname=esp8266-x.dynnamn.ru&token=2234328371&myip= нажмите enter
в devtools откройте вкладку network, щёлкните на запрос, откроется ещё вкладка, там выберите headers и чуть промотайте вниз, до request headers
скопируйте оттуда, можете хоть всё, но я думаю хватит user-agent, accept-encoding и accept-language, и отправьте после заголовка Host: серверу
client.println ("accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"); client.println ("accept-encoding: gzip, deflate, br"); client.println ("accept-language: en-US,en;q=0.9,ru;q=0.8"); client.println ("user-agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36");может, поможет, побороть cloudflare
void ddnsUpdate(void) { WiFiClient client; HTTPClient http; const uint32_t DdnsUpdateInterval = 30ul*60ul*1000ul; static uint32_t lastUpdateDdns = millis(); static bool isOK = false; String rq = "http:" +"//www." + "duckdns.org/update?domains=********&token=******************************=" + myIPv6; if (!isOK || millis() - lastUpdateDdns > DdnsUpdateInterval) { lastUpdateDdns = millis(); Serial.print("reques is:"); Serial.println(rq); if (http.begin(client, rq)) { int httpCode = http.GET(); if (httpCode > 0) { Serial.printf("[HTTP] GET... code: %d\n", httpCode); if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { String payload = http.getString(); Serial.println(payload); isOK = true; } } else { Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } http.end(); }} }Вот так это делается. Это ТОЧНО работает с DuckDNS. На 8266 (Вемос Д1). Мне было нужно с IPv6, но разницы никакой.
PS: Форум URL в коде переписывает... Чорт! Забыл как это обойти. Поделил URL на куски, так съел.
подключенные встроенные библиотеки:
к сожалению не помогло ,вообще не понимаю ,зачем они туда поставили cloudflare? это же токен явно не для ручного обновления айпи , напишу им в поддержку , а пока поищу другой бесплатный ddns.
Спасибо за помощь!