将文件上载到服务器
博哥零基础教你玩转ESP8266(十八) ESP8266 Filesystem
客户:HTML表单
<form method="post" enctype="multipart/form-data"> <input type="file" name="name"> <input class="button" type="submit" value="Upload"> </form>
服务器
建立
和
行为文件上传
功能。#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WiFiMulti.h> #include <ESP8266mDNS.h> #include <ESP8266WebServer.h> #include <FS.h> // Include the SPIFFS library ESP8266WiFiMulti wifiMulti; // Create an instance of the ESP8266WiFiMulti class, called \'wifiMulti\' ESP8266WebServer server(80); // Create a webserver object that listens for HTTP request on port 80 File fsUploadFile; // a File object to temporarily store the received file String getContentType(String filename); // convert the file extension to the MIME type bool handleFileRead(String path); // send the right file to the client (if it exists) void handleFileUpload(); // upload a new file to the SPIFFS void setup() { Serial.begin(115200); // Start the Serial communication to send messages to the computer delay(10); Serial.println(\'\n\'); wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // add Wi-Fi networks you want to connect to wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); Serial.println("Connecting ..."); int i = 0; while (wifiMulti.run() != WL_CONNECTED) { // Wait for the Wi-Fi to connect delay(1000); Serial.print(++i); Serial.print(\' \'); } Serial.println(\'\n\'); Serial.print("Connected to "); Serial.println(WiFi.SSID()); // Tell us what network we\'re connected to Serial.print("IP address:\t"); Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer if (!MDNS.begin("esp8266")) { // Start the mDNS responder for esp8266.local Serial.println("Error setting up MDNS responder!"); } Serial.println("mDNS responder started"); SPIFFS.begin(); // Start the SPI Flash Files System server.on("/upload", HTTP_GET, []() { // if the client requests the upload page if (!handleFileRead("/upload.html")) // send it if it exists server.send(404, "text/plain", "404: Not Found"); // otherwise, respond with a 404 (Not Found) error }); server.on("/upload", HTTP_POST, // if the client posts to the upload page [](){ server.send(200); }, // Send status 200 (OK) to tell the client we are ready to receive handleFileUpload // Receive and save the file ); server.onNotFound([]() { // If the client requests any URI if (!handleFileRead(server.uri())) // send it if it exists server.send(404, "text/plain", "404: Not Found"); // otherwise, respond with a 404 (Not Found) error }); server.begin(); // Actually start the server Serial.println("HTTP server started"); } void loop() { server.handleClient(); } String getContentType(String filename) { // convert the file extension to the MIME type 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(".ico")) return "image/x-icon"; else if (filename.endsWith(".gz")) return "application/x-gzip"; return "text/plain"; } bool handleFileRead(String path) { // send the right file to the client (if it exists) Serial.println("handleFileRead: " + path); if (path.endsWith("/")) path += "index.html"; // If a folder is requested, send the index file String contentType = getContentType(path); // Get the MIME type String pathWithGz = path + ".gz"; if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { // If the file exists, either as a compressed archive, or normal if (SPIFFS.exists(pathWithGz)) // If there\'s a compressed version available path += ".gz"; // Use the compressed verion File file = SPIFFS.open(path, "r"); // Open the file size_t sent = server.streamFile(file, contentType); // Send it to the client file.close(); // Close the file again Serial.println(String("\tSent file: ") + path); return true; } Serial.println(String("\tFile Not Found: ") + path); // If the file doesn\'t exist, return false return false; } void handleFileUpload(){ // upload a new file to the SPIFFS HTTPUpload& upload = server.upload(); if(upload.status == UPLOAD_FILE_START){ String filename = upload.filename; if(!filename.startsWith("/")) filename = "/"+filename; Serial.print("handleFileUpload Name: "); Serial.println(filename); fsUploadFile = SPIFFS.open(filename, "w"); // Open the file for writing in SPIFFS (create if it doesn\'t exist) filename = String(); } else if(upload.status == UPLOAD_FILE_WRITE){ if(fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize); // Write the received bytes to the file } else if(upload.status == UPLOAD_FILE_END){ if(fsUploadFile) { // If the file was successfully created fsUploadFile.close(); // Close the file again Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize); server.sendHeader("Location","/success.html"); // Redirect the client to the success page server.send(303); } else { server.send(500, "text/plain", "500: couldn\'t create file"); } } }
行为文件上传
函数只是将附加到POST请求的文件写入SPIFFS。的getContentType
功能。上传文件
关于安全的说明
高级示例
/* FSWebServer - Example WebServer with SPIFFS backend for esp8266 Copyright (c) 2015 Hristo Gochkov. All rights reserved. This file is part of the ESP8266WebServer library for Arduino environment. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA upload the contents of the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE) or you can upload the contents of a folder if you CD in that folder and run the following command: for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done access the sample web page at http://esp8266fs.local edit the page by going to http://esp8266fs.local/edit */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <FS.h> #define DBG_OUTPUT_PORT Serial #ifndef STASSID #define STASSID "your-ssid" #define STAPSK "your-password" #endif const char* ssid = STASSID; const char* password = STAPSK; const char* host = "esp8266fs"; ESP8266WebServer server(80); //holds the current upload File fsUploadFile; //format bytes String formatBytes(size_t bytes) { if (bytes < 1024) { return String(bytes) + "B"; } else if (bytes < (1024 * 1024)) { return String(bytes / 1024.0) + "KB"; } else if (bytes < (1024 * 1024 * 1024)) { return String(bytes / 1024.0 / 1024.0) + "MB"; } else { return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB"; } } 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"; } bool handleFileRead(String path) { DBG_OUTPUT_PORT.println("handleFileRead: " + path); if (path.endsWith("/")) { path += "index.htm"; } 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"); server.streamFile(file, contentType); file.close(); return true; } return false; } void handleFileUpload() { if (server.uri() != "/edit") { return; } HTTPUpload& upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { String filename = upload.filename; if (!filename.startsWith("/")) { filename = "/" + filename; } DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename); fsUploadFile = SPIFFS.open(filename, "w"); filename = String(); } else if (upload.status == UPLOAD_FILE_WRITE) { //DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize); if (fsUploadFile) { fsUploadFile.write(upload.buf, upload.currentSize); } } else if (upload.status == UPLOAD_FILE_END) { if (fsUploadFile) { fsUploadFile.close(); } DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize); } } void handleFileDelete() { if (server.args() == 0) { return server.send(500, "text/plain", "BAD ARGS"); } String path = server.arg(0); DBG_OUTPUT_PORT.println("handleFileDelete: " + path); if (path == "/") { return server.send(500, "text/plain", "BAD PATH"); } if (!SPIFFS.exists(path)) { return server.send(404, "text/plain", "FileNotFound"); } SPIFFS.remove(path); server.send(200, "text/plain", ""); path = String(); } void handleFileCreate() { if (server.args() == 0) { return server.send(500, "text/plain", "BAD ARGS"); } String path = server.arg(0); DBG_OUTPUT_PORT.println("handleFileCreate: " + path); if (path == "/") { return server.send(500, "text/plain", "BAD PATH"); } if (SPIFFS.exists(path)) { return server.send(500, "text/plain", "FILE EXISTS"); } File file = SPIFFS.open(path, "w"); if (file) { file.close(); } else { return server.send(500, "text/plain", "CREATE FAILED"); } server.send(200, "text/plain", ""); path = String(); } void handleFileList() { if (!server.hasArg("dir")) { server.send(500, "text/plain", "BAD ARGS"); return; } String path = server.arg("dir"); DBG_OUTPUT_PORT.println("handleFileList: " + path); Dir dir = SPIFFS.openDir(path); path = String(); String output = "["; while (dir.next()) { File entry = dir.openFile("r"); if (output != "[") { output += \',\'; } bool isDir = false; output += "{\"type\":\""; output += (isDir) ? "dir" : "file"; output += "\",\"name\":\""; output += String(entry.name()).substring(1); output += "\"}"; entry.close(); } output += "]"; server.send(200, "text/json", output); } void setup(void) { DBG_OUTPUT_PORT.begin(115200); DBG_OUTPUT_PORT.print("\n"); DBG_OUTPUT_PORT.setDebugOutput(true); SPIFFS.begin(); { Dir dir = SPIFFS.openDir("/"); while (dir.next()) { String fileName = dir.fileName(); size_t fileSize = dir.fileSize(); DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str()); } DBG_OUTPUT_PORT.printf("\n"); } //WIFI INIT DBG_OUTPUT_PORT.printf("Connecting to %s\n", ssid); if (String(WiFi.SSID()) != String(ssid)) { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); } while (WiFi.status() != WL_CONNECTED) { delay(500); DBG_OUTPUT_PORT.print("."); } DBG_OUTPUT_PORT.println(""); DBG_OUTPUT_PORT.print("Connected! IP address: "); DBG_OUTPUT_PORT.println(WiFi.localIP()); MDNS.begin(host); DBG_OUTPUT_PORT.print("Open http://"); DBG_OUTPUT_PORT.print(host); DBG_OUTPUT_PORT.println(".local/edit to see the file browser"); //SERVER INIT //list directory server.on("/list", HTTP_GET, handleFileList); //load editor server.on("/edit", HTTP_GET, []() { if (!handleFileRead("/edit.htm")) { server.send(404, "text/plain", "FileNotFound"); } }); //create file server.on("/edit", HTTP_PUT, handleFileCreate); //delete file server.on("/edit", HTTP_DELETE, handleFileDelete); //first callback is called after the request has ended with all parsed arguments //second callback handles file uploads at that location server.on("/edit", HTTP_POST, []() { server.send(200, "text/plain", ""); }, handleFileUpload); //called when the url is not defined here //use it to load content from SPIFFS server.onNotFound([]() { if (!handleFileRead(server.uri())) { server.send(404, "text/plain", "FileNotFound"); } }); //get heap status, analog input value and all GPIO statuses in one json call server.on("/all", HTTP_GET, []() { String json = "{"; json += "\"heap\":" + String(ESP.getFreeHeap()); json += ", \"analog\":" + String(analogRead(A0)); json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16))); json += "}"; server.send(200, "text/json", json); json = String(); }); server.begin(); DBG_OUTPUT_PORT.println("HTTP server started"); } void loop(void) { server.handleClient(); MDNS.update(); }
实际项目
物料准备:
ESP8266 *1
TFT彩屏 *1 (驱动IC:ST7735S)
杜邦线若干
导线连接:
ESP8266--------------------TFT
- GPIO4--------------------RST
- GPIO5--------------------D/C
- GPIO13(MOSI)-----------DIN(SDI,MOSI)
- GPIO14(SCK)-------------CLK(SCK)
- GPIO15(SS,CS)-----------CS(SS)
- 3.3V----------------------3.3V,LED+100R电阻
- GND---------------------GND
(括号里的为同一个io不同称呼)
工作流程:
8266连接路由器-->8266建立web服务器-->电脑访问web页面-->上传图片-->保存图片到flash-->读取图片数据-->发送个给tft显示
准备工作:
1.安装arduino ide for esp8266(使用arduino ide开发8266).
2.加载附件中的库文件到ide目录中。(ST7735S库略微修改过给8266使用)
3.看看示例我们知道了这个tft屏的用法。
4.下载烧录附件中的源码。
5.可选,安装附件中的Bonjour服务,用于mdns,可在浏览器输入域名访问8266的web,直接访问esp8266fs.local即可
下载固件完成后,打开串口监视器等待8266连接路由器,值得注意的是如果这片8266第一次使用spiffs可能需要1-2分钟的格式化时间。
开始工作:
1.待8266正常工作完成后,打开串口监视器中查看ip地址。
2.在浏览器打开串口监视器中获取到的ip地址访问8266,如果安装了Bonjour服务直接访问esp8266fs.local
3.选择需要显示的图片,本程序只做了显示bmp格式的图片,所以上传的文件附件必须为bmp格式并且分辨率为128*128,24位
4.点击上传,待文件上传完成就可以看到上传的图片了
工程文件
上面两个是库文件,但在该对应目录下。
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <FS.h> #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> #define TFT_CS 15 // Chip select line for TFT display #define TFT_RST 4 // Reset line for TFT (or see below...) #define TFT_DC 5 // Data/command line for TFT //wifi配置 const char* ssid = "love"; const char* password = "love123456"; const char* host = "esp8266"; // const char mainPageString[] PROGMEM = "<!DOCTYPE html>\r\n\ <html>\r\n\ <head>\r\n\ <meta http-equiv=\'Content-type\' content=\'text/html; charset=utf-8\'>\r\n\ <title>ESP Monitor</title>\r\n\ </head>\r\n\ <body>\r\n\ <img src=\'/logo.bmp\' width=\'128\' height=\'128\' />\r\n\ <form method=\'POST\' action=\'/\' enctype=\'multipart/form-data\'>\r\n\ <input type=\'file\' name=\'update\' id=\'update\'><input type=\'submit\' value=\'提交\'></form>\r\n\ 文件格式必须为bmp,24位深,本示例使用的屏幕为1.44寸TFT,分辨率128*128,ic:ST7735\r\n\ </body>\r\n\ </html>"; //监听80端口 ESP8266WebServer server(80); Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); File fsUploadFile; #define BUFFPIXEL 20 // These read 16- and 32-bit types from the SD card file. // BMP data is stored little-endian, Arduino is little-endian too. // May need to reverse subscript order if porting elsewhere. uint16_t read16(File f) { uint16_t result; ((uint8_t *)&result)[0] = f.read(); // LSB ((uint8_t *)&result)[1] = f.read(); // MSB return result; } uint32_t read32(File f) { uint32_t result; ((uint8_t *)&result)[0] = f.read(); // LSB ((uint8_t *)&result)[1] = f.read(); ((uint8_t *)&result)[2] = f.read(); ((uint8_t *)&result)[3] = f.read(); // MSB return result; } void bmpDraw(char *filename, uint8_t x, uint8_t y) { File bmpFile; int bmpWidth, bmpHeight; // W+H in pixels uint8_t bmpDepth; // Bit depth (currently must be 24) uint32_t bmpImageoffset; // Start of image data in file uint32_t rowSize; // Not always = bmpWidth; may have padding uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel) uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer boolean goodBmp = false; // Set to true on valid header parse boolean flip = true; // BMP is stored bottom-to-top int w, h, row, col; uint8_t r, g, b; uint32_t pos = 0, startTime = millis(); if((x >= tft.width()) || (y >= tft.height())) return; Serial.println(); Serial.print("Loading image \'"); Serial.print(filename); Serial.println(\'\\'\'); bmpFile = SPIFFS.open(filename,"r"); // Open requested file on SD card if (!bmpFile) { Serial.print("File not found"); return; } // Parse BMP header if(read16(bmpFile) == 0x4D42) { // BMP signature Serial.print("File size: "); Serial.println(read32(bmpFile)); (void)read32(bmpFile); // Read & ignore creator bytes bmpImageoffset = read32(bmpFile); // Start of image data Serial.print("Image Offset: "); Serial.println(bmpImageoffset, DEC); // Read DIB header Serial.print("Header size: "); Serial.println(read32(bmpFile)); bmpWidth = read32(bmpFile); bmpHeight = read32(bmpFile); if(read16(bmpFile) == 1) { // # planes -- must be \'1\' bmpDepth = read16(bmpFile); // bits per pixel Serial.print("Bit Depth: "); Serial.println(bmpDepth); if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed goodBmp = true; // Supported BMP format -- proceed! Serial.print("Image size: "); Serial.print(bmpWidth); Serial.print(\'x\'); Serial.println(bmpHeight); // BMP rows are padded (if needed) to 4-byte boundary rowSize = (bmpWidth * 3 + 3) & ~3; // If bmpHeight is negative, image is in top-down order. // This is not canon but has been observed in the wild. if(bmpHeight < 0) { bmpHeight = -bmpHeight; flip = false; } // Crop area to be loaded w = bmpWidth; h = bmpHeight; if((x+w-1) >= tft.width()) w = tft.width() - x; if((y+h-1) >= tft.height()) h = tft.height() - y; // Set TFT address window to clipped image bounds tft.setAddrWindow(x, y, x+w-1, y+h-1); for (row=0; row<h; row++) { // For each scanline... // Seek to start of scan line. It might seem labor- // intensive to be doing this on every line, but this // method covers a lot of gritty details like cropping // and scanline padding. Also, the seek only takes // place if the file position actually needs to change // (avoids a lot of cluster math in SD library). if(flip) // Bitmap is stored bottom-to-top order (normal BMP) pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize; else // Bitmap is stored top-to-bottom pos = bmpImageoffset + row * rowSize; if(bmpFile.position() != pos) { // Need seek? bmpFile.seek(pos,SeekSet); buffidx = sizeof(sdbuffer); // Force buffer reload } for (col=0; col<w; col++) { // For each pixel... // Time to read more pixel data? if (buffidx >= sizeof(sdbuffer)) { // Indeed bmpFile.read(sdbuffer, sizeof(sdbuffer)); buffidx = 0; // Set index to beginning } // Convert pixel from BMP to TFT format, push to display b = sdbuffer[buffidx++]; g = sdbuffer[buffidx++]; r = sdbuffer[buffidx++]; tft.pushColor(tft.Color565(r,g,b)); } // end pixel } // end scanline Serial.print("Loaded in "); Serial.print(millis() - startTime); Serial.println(" ms"); } // end goodBmp } } bmpFile.close(); if(!goodBmp) Serial.println("BMP format not recognized."); } //format bytes String formatBytes(size_t bytes){ if (bytes < 1024){ return String(bytes)+"B"; } else if(bytes < (1024 * 1024)){ return String(bytes/1024.0)+"KB"; } else if(bytes < (1024 * 1024 * 1024)){ return String(bytes/1024.0/1024.0)+"MB"; } else { return String(bytes/1024.0/1024.0/1024.0)+"GB"; } } //文件格式转换 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"; } //读取spiffs中的文件 bool handleFileRead(String path){ Serial.println("handleFileRead: " + path); if(path.endsWith("/")) path += "index.htm"; 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 true; } return false; } //上传文件到spiffs中 void handleFileUpload(){ if(server.uri() != "/") return; HTTPUpload& upload = server.upload(); if(upload.status == UPLOAD_FILE_START){ String filename = upload.filename; if(!filename.startsWith("/")) filename = "/"+filename; Serial.print("handleFileUpload Name: "); Serial.println(filename); SPIFFS.remove("/logo.bmp"); fsUploadFile = SPIFFS.open("/logo.bmp", "w"); filename = String(); } else if(upload.status == UPLOAD_FILE_WRITE){ //Serial.print("handleFileUpload Data: "); Serial.println(upload.currentSize); if(fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize); } else if(upload.status == UPLOAD_FILE_END){ if(fsUploadFile) fsUploadFile.close(); Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize); bmpDraw("/logo.bmp", 0, 0); } } void handleRoot() { server.send(200, "text/html", mainPageString); server.client().stop(); } void uplaodFinish() { server.send(200, "text/html", mainPageString); } void setup(void){ Serial.begin(115200); Serial.print("\n"); Serial.setDebugOutput(true); SPIFFS.begin(); { Dir dir = SPIFFS.openDir("/"); while (dir.next()) { String fileName = dir.fileName(); size_t fileSize = dir.fileSize(); Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str()); } Serial.printf("\n"); } tft.initR(INITR_144GREENTAB); bmpDraw("/logo.bmp", 0, 0); delay(2000); //WIFI INIT Serial.printf("Connecting to %s\n", ssid); WiFi.disconnect(); WiFi.mode(WIFI_STA); if (String(WiFi.SSID()) != String(ssid)) { WiFi.begin(ssid, password); } while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected! IP address: "); Serial.println(WiFi.localIP()); MDNS.begin(host); Serial.print("Open http://"); Serial.print(host); Serial.println(".local/ to see the file browser"); //SERVER INIT server.on("/", HTTP_GET, handleRoot); //把上传的数据保存到spiffs server.on("/", HTTP_POST,[](){uplaodFinish();}, handleFileUpload); //访问的url没有在找spiffs中找到回复404 //访问的url没有在找spiffs中找到回复404 server.onNotFound([](){ if(!handleFileRead(server.uri())) server.send(404, "text/plain", "FileNotFound"); }); server.begin(); Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); }