ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)

目录

    • 前言
    • Web配网详解
    • 强制门户详解
    • 完整代码
    • 实验效果

前言

1.Web配网概述
在应用到esp8266的场景,往往与wifi是离不开的,但用户的wifi账号密码又无从知晓,于是乎有了配网。
目前,市面上的配网方式多种多样,但其中博主觉得成功率最高,最方便的方式其实还是Web配网(个人看法),因为Web配网从根本来说就是esp8266开启一个web服务器,在此基础上进行信息交互(POST,GET),所以信息的传输较为稳定,配网成功率高。
2.强制门户概述
强制门户:连接上wifi以后,手机会自动打开一个网页,这就是强制门户。
相信大家遇见过很多拥有免费wifi的地方,连接上wifi以后,就会自动弹出认证界面,在Web配网的基础上,我们加上强制门户,就可以实现连接wifi以后自动打开配网界面,方便用户操作。

Web配网详解

想要实现Web配网,就需要让esp8266开启一个WebServer服务器,需要用到以下函数

ESP8266WebServer();//创建WebServer
begin();//启动WebServer
on();//请求响应回调
onNotFound();//无法响应的请求的回调函数
send();//发送响应数据
hasArg();//是否存在某个参数
args();//获取参数个数

具体WebServer实现代码

const char* AP_NAME = "配网WIFI";//wifi名字
//html网页源码
const char* page_html = "\
\r\n\
\r\n\
\r\n\
  \r\n\
  \r\n\
  Document\r\n\
\r\n\
\r\n\
  
\r\n\ wifi名称:
\r\n\
\r\n\ wifi密码:
\r\n\
\r\n\ \r\n\
\r\n\ \r\n\ \r\n\ "
; IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址 ESP8266WebServer server(80);//创建WebServer void initBasic(void){//初始化基础 Serial.begin(115200); WiFi.hostname("Smart-ESP8266");//设置ESP8266设备名 } void initSoftAP(void){//初始化AP模式 WiFi.mode(WIFI_AP); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); if(WiFi.softAP(AP_NAME)){ Serial.println("ESP8266 SoftAP is right"); } } void handleRoot() {//访问主页回调函数 server.send(200, "text/html", page_html); } void handleRootPost() {//Post回调函数 Serial.println("handleRootPost"); if (server.hasArg("ssid")) {//判断是否有账号参数 Serial.print("got ssid:"); strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中 Serial.println(sta_ssid); } else {//没有参数 Serial.println("error, not found ssid"); server.send(200, "text/html", "error, not found ssid");//返回错误页面 return; } //密码与账号同理 if (server.hasArg("password")) { Serial.print("got password:"); strcpy(sta_password, server.arg("password").c_str()); Serial.println(sta_password); } else { Serial.println("error, not found password"); server.send(200, "text/html", "error, not found password"); return; } server.send(200, "text/html", "保存成功");//返回保存成功页面 delay(2000); //连接wifi connectNewWifi(); } void initWebServer(void){//初始化WebServer server.on("/", HTTP_GET, handleRoot);//设置主页回调函数 server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数 server.begin();//启动WebServer Serial.println("WebServer started!"); } void connectNewWifi(void){ WiFi.mode(WIFI_STA);//切换为STA模式 WiFi.setAutoConnect(true);//设置自动连接 WiFi.begin();//连接上一次连接成功的wifi Serial.println(""); Serial.print("Connect to wifi"); int count = 0; while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } if(WiFi.status() == WL_CONNECTED){//如果连接上 就输出IP信息 防止未连接上break后会误输出 Serial.println(""); Serial.println("WIFI Connected!"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.stop(); } } void setup() { initBasic(); initSoftAP(); initWebServer(); } void loop() { server.handleClient(); dnsServer.processNextRequest(); }

强制门户详解

要想实现强制门户,就要在以上的普通Web配网的基础上加上DNS服务。
具体实现思路:当手机连接上一个无需密码的wifi后(看上面的initSoftAP就可以发现设置的是无需密码的AP),会访问一个手机内部的网址去查看是否可以上网,在访问此网址的时候会先发起DNS请求,向服务器问域名的IP地址。然后再发起HTTP请求,请求想要的内容。
ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)_第1张图片
esp8266充当AP的角色,会收到手机发来的DNS请求,这时将请求的IP地址指向esp8266的地址就可以了。这时手机就会向esp8266发送http请求,esp8266不管收到什么http请求,都将html页面回复过去,就可以实现强制门户功能了。
将请求IP指向esp8266地址代码:

DNSServer dnsServer;//创建dnsServer实例
IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址
const byte DNS_PORT = 53;//DNS端口号

dnsServer.start(DNS_PORT, "*", apIP)

不管收到什么http请求,都将html页面回复过去

  ESP8266WebServer server(80);//创建WebServer
  
  //server.on("/",handleRoot);
  //上面那行必须在第二个参数上添加上HTTP_GET才能不影响强制门户,防止有些设备无法弹出强制门户,要用域名访问,如果不加第二个参数,就只能实现域名访问而无法强制门户
  //在无法响应的http请求响应回调设置为主页的回调函数,才可以强制门户
  server.on("/", HTTP_GET, handleRoot);//设置主页回调函数
  server.onNotFound(handleRoot);//设置无法响应的http请求的回调函数
  server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数
  server.begin();//启动WebServer

完整代码

#include 
#include 
#include 

const char* AP_NAME = "配网WIFI";//wifi名字
//暂时存储wifi账号密码
char sta_ssid[32] = {0};
char sta_password[64] = {0};
//配网页面代码
const char* page_html = "\
\r\n\
\r\n\
\r\n\
  \r\n\
  \r\n\
  Document\r\n\
\r\n\
\r\n\
  
\r\n\ wifi名称:
\r\n\
\r\n\ wifi密码:
\r\n\
\r\n\ \r\n\
\r\n\ \r\n\ \r\n\ "
; const byte DNS_PORT = 53;//DNS端口号 IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP地址 DNSServer dnsServer;//创建dnsServer实例 ESP8266WebServer server(80);//创建WebServer void handleRoot() {//访问主页回调函数 server.send(200, "text/html", page_html); } void handleRootPost() {//Post回调函数 Serial.println("handleRootPost"); if (server.hasArg("ssid")) {//判断是否有账号参数 Serial.print("got ssid:"); strcpy(sta_ssid, server.arg("ssid").c_str());//将账号参数拷贝到sta_ssid中 Serial.println(sta_ssid); } else {//没有参数 Serial.println("error, not found ssid"); server.send(200, "text/html", "error, not found ssid");//返回错误页面 return; } //密码与账号同理 if (server.hasArg("password")) { Serial.print("got password:"); strcpy(sta_password, server.arg("password").c_str()); Serial.println(sta_password); } else { Serial.println("error, not found password"); server.send(200, "text/html", "error, not found password"); return; } server.send(200, "text/html", "保存成功");//返回保存成功页面 delay(2000); //连接wifi connectNewWifi(); } void initBasic(void){//初始化基础 Serial.begin(115200); WiFi.hostname("Smart-ESP8266");//设置ESP8266设备名 } void initSoftAP(void){//初始化AP模式 WiFi.mode(WIFI_AP); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); if(WiFi.softAP(AP_NAME)){ Serial.println("ESP8266 SoftAP is right"); } } void initWebServer(void){//初始化WebServer //server.on("/",handleRoot); //上面那行必须以下面这种格式去写否则无法强制门户 server.on("/", HTTP_GET, handleRoot);//设置主页回调函数 server.onNotFound(handleRoot);//设置无法响应的http请求的回调函数 server.on("/", HTTP_POST, handleRootPost);//设置Post请求回调函数 server.begin();//启动WebServer Serial.println("WebServer started!"); } void initDNS(void){//初始化DNS服务器 if(dnsServer.start(DNS_PORT, "*", apIP)){//判断将所有地址映射到esp8266的ip上是否成功 Serial.println("start dnsserver success."); } else Serial.println("start dnsserver failed."); } void connectNewWifi(void){ WiFi.mode(WIFI_STA);//切换为STA模式 WiFi.setAutoConnect(true);//设置自动连接 WiFi.begin();//连接上一次连接成功的wifi Serial.println(""); Serial.print("Connect to wifi"); int count = 0; while (WiFi.status() != WL_CONNECTED) { delay(500); count++; if(count > 10){//如果5秒内没有连上,就开启Web配网 可适当调整这个时间 initSoftAP(); initWebServer(); initDNS(); break;//跳出 防止无限初始化 } Serial.print("."); } Serial.println(""); if(WiFi.status() == WL_CONNECTED){//如果连接上 就输出IP信息 防止未连接上break后会误输出 Serial.println("WIFI Connected!"); Serial.print("IP address: "); Serial.println(WiFi.localIP());//打印esp8266的IP地址 server.stop(); } } void setup() { initBasic(); connectNewWifi(); } void loop() { server.handleClient(); dnsServer.processNextRequest(); }

实验效果

ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)_第2张图片
ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)_第3张图片

如果有什么不懂的可以评论咨询,看到会回复,欢迎讨论!

你可能感兴趣的:(ESP8266开发教程,c语言,c++,http,html)