網友教程:https://blog.csdn.net/solar_Lan/article/details/74231360
通過網友教程,我們搭建了文件系統。在此基礎上,我們增加WIFI交互。
現有功能:
1 輸入默認WIFI信息,ESP8266上電后直接連接,得到分配的IP
2 網頁同一個局域網下訪問IP,出現配置界面,告訴ESP8266要連接的WIFI信息
未來需要加入;
1 ESP8266上電進入AP_STA模式,固定IP194.168.4.1 等待手機連接AP熱點,通過網頁輸入目標WIFI賬號和密碼。
2 ESP8266接收到WIFI信息后,自己去鏈接。完成配網功能

esp8266代碼
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
ESP8266WebServer server ( 80 );
String ssid = "HUAWEI-H3VBKZ"; // 需要連接的wifi熱點名稱
String password ="13991320168"; // 需要連接的wifi熱點密碼
/**
* 根據文件后綴獲取html協議的返回內容類型
*/
String getContentType(String filename){
if(server.hasArg("download")) return "application/octet-stream";
else if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
else if(filename.endsWith(".css")) return "text/css";
else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".png")) return "image/png";
else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
/* NotFound處理
* 用於處理沒有注冊的請求地址
* 一般是處理一些頁面請求
*/
void handleNotFound() {
String path = server.uri();
Serial.print("load url:");
Serial.println(path);
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if(SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)){
if(SPIFFS.exists(pathWithGz))
path += ".gz";
File file = SPIFFS.open(path, "r");
size_t sent = server.streamFile(file, contentType);
file.close();
return;
}
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for ( uint8_t i = 0; i < server.args(); i++ ) {
message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
}
server.send ( 404, "text/plain", message );
}
void handleMain() {
/* 返回信息給瀏覽器(狀態碼,Content-type, 內容)
* 這里是訪問當前設備ip直接返回一個String
*/
Serial.print("handleMain");
File file = SPIFFS.open("/index.html", "r");
size_t sent = server.streamFile(file, "text/html");
file.close();
return;
}
/* 引腳更改處理
* 訪問地址為htp://192.162.xxx.xxx/pin?a=XXX的時候根據a的值來進行對應的處理
*/
void handlePin() {
if(server.hasArg("a")) { // 請求中是否包含有a的參數
String action = server.arg("a"); // 獲得a參數的值
if(action == "on") { // a=on
digitalWrite(2, LOW); // 點亮8266上的藍色led,led是低電平驅動,需要拉低才能亮
server.send ( 200, "text/html", "Pin 2 has turn on"); return; // 返回數據
} else if(action == "off") { // a=off
digitalWrite(2, HIGH); // 熄滅板載led
server.send ( 200, "text/html", "Pin 2 has turn off"); return;
}
server.send ( 200, "text/html", "unknown action"); return;
}
server.send ( 200, "text/html", "action no found");
}
void handleWifi(){
if(server.hasArg("config")) { // 請求中是否包含有a的參數
String config = server.arg("config"); // 獲得a參數的值
String wifiname;
String wifipwd;
if(config == "on") { // a=on
if(server.hasArg("name")) { // 請求中是否包含有a的參數
wifiname = server.arg("name"); // 獲得a參數的值
}
if(server.hasArg("pwd")) { // 請求中是否包含有a的參數
wifipwd = server.arg("pwd"); // 獲得a參數的值
}
String backtxt= "已經連接WIFI! 名稱:"+ wifiname +" 密碼:"+ wifipwd ;
server.send ( 200, "text/html", backtxt);
return;
} else if(config == "off") { // a=off
server.send ( 200, "text/html", "config is off!");
return;
}
server.send ( 200, "text/html", "unknown action"); return;
}
server.send ( 200, "text/html", "action no found");
}
void setup() {
// 日常初始化網絡
pinMode(2, OUTPUT);
Serial.begin ( 115200 );
SPIFFS.begin();
int connectCount = 0;
WiFi.begin ( ssid.c_str(), password.c_str() );
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 1000 );
Serial.print ( "." );
if(connectCount > 30) {
Serial.println( "Connect fail!" );
break;
}
connectCount += 1;
}
if(WiFi.status() == WL_CONNECTED) {
Serial.println ( "" );
Serial.print ( "Connected to " );
Serial.println ( ssid );
Serial.print ( "IP address: " );
Serial.println ( WiFi.localIP() );
connectCount = 0;
}
server.on ("/", handleMain); // 綁定‘/’地址到handleMain方法處理
server.on ("/pin", HTTP_GET, handlePin); // 綁定‘/pin’地址到handlePin方法處理
server.on ("/wifi", HTTP_GET, handleWifi); // 綁定‘/pin’地址到handlePin方法處理
server.onNotFound ( handleNotFound ); // NotFound處理
server.begin();
Serial.println ( "HTTP server started" );
}
void loop() {
/* 循環處理,因為ESP8266的自帶的中斷已經被系統占用,
* 只能用過循環的方式來處理網絡請求
*/
server.handleClient();
}
esp8266 flash中要存的網頁信息
網友未修改的網頁文件 鏈接:https://pan.baidu.com/s/1vk6xmsYZuJe8CMFzJNKdJw 密碼:oiz2
工程文件夾同目錄 data

data文件夾下

自己修改 index網頁文件
直接打開的樣子(沒有布局文件)
---比較丑陋---
通過ESP8266返回打開i的樣子(加載了布局文件)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP8266 配置信息</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">ESP8266</a>
</div>
</div>
</nav>
<div class="container">
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="#">主頁</a></li>
<li role="presentation" class="active"><a href="#">其它</a></li>
</ul>
<div class="starter-template">
<h1>歡迎</h1>
<button onclick='setPinValue("on")' >點亮板載LED</button></br>
<button onclick='setPinValue("off")' >熄滅板載LED</button>
<p>狀態消息: <span id="txtState"></span></p>
</div>
<div class="starter-template">
<h3>連接WIFI:</h3>
<form action="">
名稱: <input type="text" id="wifiname" />
</form>
<form action="">
密碼: <input type="text" id="wifipwd" />
</form></br>
<button onclick='setWifi(wifiname.value,wifipwd.value)' >連接</button>
<p>連接狀態: <span id="wifiState"></span></p>
</div>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
function setPinValue(value) {
alert("按鍵點擊!");
var xmlhttp;
if (value.length==0)
{
document.getElementById("txtState").innerHTML="請點擊正確按鍵!";
return;
}
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 瀏覽器執行代碼
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200){
//alert(xmlhttp.responseText);
//alert("操作成功");
document.getElementById("txtState").innerHTML = xmlhttp.responseText;
}
}
var requestString = "/pin?a=" + value + "&pin=2";
xmlhttp.open("GET", requestString, true);
xmlhttp.send(null);
}
function setWifi(name,pwd) {
alert("按鍵點擊!");
var xmlhttp;
if (name.length==0)
{
document.getElementById("wifiState").innerHTML="請輸入WIFI信息!";
return;
}
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行代碼
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 瀏覽器執行代碼
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200){
//alert(xmlhttp.responseText);
//alert("操作成功");
document.getElementById("wifiState").innerHTML = xmlhttp.responseText;
}
}
var requestString = "/wifi?config=on" + "&name="+name+"&pwd="+pwd;
xmlhttp.open("GET", requestString, true);
xmlhttp.send(null);
}
</script>
</body>
</html>
