带有 HTML 请求和 ESPAsyncWebServer 库的 ESP32

问题描述 投票:0回答:1

我想使用 ESPAsyncWebServer 库在 ESP32 上运行一个简单的 Web 服务器。在网页上,您应该能够选择要上传到 SD 卡的文件。您还应该能够从下拉菜单中选择将文件上传到三个目录中的哪一个。文件已上传,但仅上传至根目录,未上传至相应文件夹。变量“目录”始终为空。显然该请求无法正常工作。我究竟做错了什么?感谢您的帮助!

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <SD.h>
#include <SPIFFS.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
#define SCREEN_ADDRESS 0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char* ssid = "myWifi";
const char* password = "myPassword";

AsyncWebServer server(80);

void setup() {
  Serial.begin(115200);

  if (!SD.begin()) {
    Serial.println("Failed to mount SD card.");
    return;
  }

  if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }

  Serial.println("Connected to WiFi");

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/html", getWebpage());
  });

  server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request) {
    request->send(200);
  }, handleUpload);

  server.begin();
}

void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t       len, bool final) {
  static File file;
  static String path;

  if (!index) {
    String directory = request->arg("selektor");
    path = "/" + directory + "/" + filename;
    file = SD.open(path, FILE_WRITE);
    Serial.println("Verzeichnis: " + path);
  }

  if (file) {
    for (size_t i = 0; i < len; i++) {
      file.write(data[i]);
    }

    if (final) {
      file.close();
      display.clearDisplay();
      display.setCursor(0,0);
      display.println("Datei hochgeladen:");
      display.println(filename);
      display.display();
    }
  }
}

void loop() {
}

String getWebpage() {
    String page = "<!DOCTYPE html><html><head><title>ESP32 Option Selector</title></head><body>";
    page += "<form method='POST' action='/upload' enctype='multipart/form-data'><input type='file'      name='upload'><br><select name='selektor'>";
    page += "<form action='/submit' method='post'>";
    page += "<option value='dir1'>Directory 1</option>";
    page += "<option value='dir2'>Directory 2</option>";
    page += "<option value='dir3'>Directory 3</option>";
    page += "</select><input type='submit' value='Upload'></form></body></html>";
  return page;
}
html webserver esp32 arduino-esp32
1个回答
0
投票

ESP32AsyncWebServer POST 请求的 API 有 3 个回调函数:

server.on("/uri", HTTP_POST, onRequest, onFileUpload, onBody);

针对不同的应用场景,每个回调都有不同的参数。

使用哪个回调函数取决于 POST 请求的类型以及从客户端发送到服务器的数据的组合。如果仅包含 post 请求有效负载(例如序列化的 json 对象),则使用

onBody()
;当您请求仅包含要上传的文件(其中已提供文件名和文件数据、长度)时,使用
onFileUpload()
回调作为回调函数的参数。对于
multipart
负载,它可以包含文件和进一步的请求正文,您需要使用
onRequest()
回调,
onRequest()
函数参数仅包含
request
对象,但您可以获得所有类型通过调用相关请求方法获取您需要的数据。

因此,对于您的情况,您将需要使用

onRequest()
回调。


void onRequest(AsyncWebServerRequest *request) {
  
  if (request->hasArg("upload") && request->hasArg("selektor")) {
    String path = "/" + request->arg("selektor") + "/" + request->arg("upload");
    Serial.printf("path %s\n", path.c_str());
    request->send(200, "text/plain", "Ok");
  }
  else {
    request->send(400, "text/plain", "Bad request");
  }

}

void setup() {
  
  // other setup codes omitted here

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/html", getWebpage());
  });

  server.on("/upload", HTTP_POST, onRequest);

  server.begin();
}
© www.soinside.com 2019 - 2024. All rights reserved.