esp32 基于esp-idf 的网页服务
·
一、代码
ESP32 IDF框架的网页服务器,包含WiFi连接(AP+STA)、HTTP服务、前端交互和硬件控制功能:
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_http_server.h"
#include "driver/gpio.h"
#include "cJSON.h"
// WiFi配置
#define WIFI_SSID "adb"
#define WIFI_PASS "abc@0102"
#define LED_GPIO GPIO_NUM_2 // 板载LED引脚
// 全局变量
static const char *TAG = "WEB_SERVER";
static httpd_handle_t server = NULL;
static bool led_state = false;
// WiFi连接初始化
static void wifi_init_sta(void) {
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
.threshold.authmode = WIFI_AUTH_WPA2_PSK
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "WiFi初始化完成,正在连接AP...");
}
// 事件处理
static int s_retry_num = 0;
// 事件处理
static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
esp_wifi_connect();
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < 6)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
else
{
ESP_LOGI(TAG,"connect to the AP fail");
}
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "获得IP地址: " IPSTR, IP2STR(&event->ip_info.ip));
start_webserver();
s_retry_num=0;
}
}
// HTTP请求处理函数
static esp_err_t root_get_handler(httpd_req_t *req) {
extern const char index_html_start[] asm("_binary_index_html_start");
extern const char index_html_end[] asm("_binary_index_html_end");
extern const unsigned int len2 asm ("index_html_length");
printf("len2=%d\n",len2);
printf("len=%d\n",index_html_end-index_html_start);
printf("strlen(index_html_start)=%d\n",strlen(index_html_start));
httpd_resp_set_type(req, "text/html");
//strlen(index_html_start) 获取的长度比实际的多2个字节
httpd_resp_send(req, index_html_start, len2);
return ESP_OK;
}
static esp_err_t led_post_handler(httpd_req_t *req) {
char buf[10];
int ret = httpd_req_recv(req, buf, sizeof(buf));
if (ret > 0) {
buf[ret] = '\0';
if (strcmp(buf, "toggle") == 0) {
led_state = !led_state;
gpio_set_level(LED_GPIO, led_state);
httpd_resp_sendstr(req, led_state ? "ON" : "OFF");
}
}
return ESP_OK;
}
static esp_err_t sensor_get_handler(httpd_req_t *req) {
// 模拟传感器数据(实际项目应替换为真实传感器读取)
cJSON *root = cJSON_CreateObject();
cJSON_AddNumberToObject(root, "temperature", 25.6);
cJSON_AddNumberToObject(root, "humidity", 65.2);
const char *json_str = cJSON_PrintUnformatted(root);
httpd_resp_set_type(req, "application/json");
httpd_resp_sendstr(req, json_str);
cJSON_Delete(root);
free((void*)json_str);
return ESP_OK;
}
// 启动Web服务器
void start_webserver() {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_uri_handlers = 8;
// 注册URI处理器
httpd_uri_t uri_get = {
.uri = "/",
.method = HTTP_GET,
.handler = root_get_handler,
.user_ctx = NULL
};
httpd_uri_t uri_led = {
.uri = "/led",
.method = HTTP_POST,
.handler = led_post_handler,
.user_ctx = NULL
};
httpd_uri_t uri_sensor = {
.uri = "/sensor",
.method = HTTP_GET,
.handler = sensor_get_handler,
.user_ctx = NULL
};
if (httpd_start(&server, &config) == ESP_OK) {
httpd_register_uri_handler(server, &uri_get);
httpd_register_uri_handler(server, &uri_led);
httpd_register_uri_handler(server, &uri_sensor);
ESP_LOGI(TAG, "HTTP服务器启动成功");
}
}
void app_main(void) {
// 初始化NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// 初始化GPIO
gpio_reset_pin(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
// 初始化网络
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 注册事件处理器
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
// 启动WiFi
wifi_init_sta();
}
二、配套HTML文件 (index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32控制面板</title>
<style>
body { font-family: Arial; text-align: center; margin: 40px; }
.btn {
padding: 15px 30px;
font-size: 18px;
background: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.status { margin-top: 20px; font-size: 20px; }
</style>
</head>
<body>
<h1>ESP32控制面板</h1>
<button class="btn" onclick="toggleLED()">切换LED状态</button>
<div class="status">
<p>传感器数据: <span id="sensorData">加载中...</span></p>
</div>
<script>
function toggleLED() {
fetch('/led', {
method: 'POST',
body: 'toggle'
})
.then(response => response.text())
.then(state => {
alert('当前LED状态: ' + state);
});
}
// 每2秒更新传感器数据
setInterval(() => {
fetch('/sensor')
.then(response => response.json())
.then(data => {
document.getElementById('sensorData').innerHTML =
`${data.temperature}℃ / ${data.humidity}%`;
});
}, 2000);
</script>
</body>
</html>
三、工程结构
my_web_server/
├── CMakeLists.txt
├── main/
│ ├── CMakeLists.txt
│ └── main.c # 上述C代码
└── components/
└── web_files/
└── index.html # 上述HTML文件
四、功能说明
1、硬件控制:通过GPIO2控制板载LED
2、数据接口:
GET /:返回控制页面
POST /led:切换LED状态
GET /sensor:获取模拟传感器数据
3、前端功能:
实时显示传感器数据(每2秒更新)
按钮控制LED状态
响应式界面设计
4、测试验证
- 查看串口输出的IP地址
- 浏览器访问
http://[ESP32_IP]/ - 点击按钮测试LED控制
- 观察传感器数据更新
代码实现了完整的Web服务器功能,如需扩展功能可在此基础上添加更多URI处理逻辑。

<style>
.menu_button {
width: 100%;
height: 50px;
border-radius: 4px;
text-align: center;
cursor: pointer;
display: block;
margin-bottom: 5px;
font: 14px/50px Tahoma;
transition: all 0.18s ease-in-out;
border: 1px solid #4FD666;
background: linear-gradient(to top right, #3EC97A, #69EA49 20%, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, 0)) top right/500% 500%;
color: green;
}
.menu_button:hover {
color: white;
background-position: bottom left;
}
.hidden_input {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.imgBox {
border: 2px dashed green;
border-radius: 8px;
background: lightyellow;
background-repeat: no-repeat;
text-align: center;
margin-top: 10px;
}
.mesBox {
margin: 100px 70px;
color: green;
font-size: 25px;
font-family: Verdana, Arial, sans-serif;
}
.header_back {
width: 100%;
height: 20px;
background: #EEEEEE;
}
.content_back {
width: 100%;
background: #EEEEEE;
}
.footer_back {
width: 100%;
height: 20px;
background: #EEEEEE;
}
.header_face {
width: 100%;
height: 20px;
margin: 0 auto;
background: #ebefeb;
}
.content_face {
width: 100%;
height: 100%;
margin: 0 auto;
background: #FFFFFF;
}
.footer_face {
width: 100%;
height: 100%;
margin: 0 auto;
background: #CCFFCC;
}
.menu_bar {
border-right: 1px solid #4FD666;
background: #EEFFEE;
vertical-align: top;
padding: 15px;
width: 200px;
height: 100%
}
.content_body {
vertical-align: top;
text-align: center;
height: 100%;
padding: 30px;
padding-left: 15px;
}
.title {
color: green;
font-size: 32px;
font-family: arial;
}
.comment {
width: 100%;
color: green;
font-size: 16px;
font-style: italic;
font-family: arial;
text-align: center;
}
.nud {
width: 70px;
}
</style>
<script type="text/javascript">
var srcBox, srcImg, dstImg;
var epdArr, epdInd, palArr;
var curPal;
function getElm(n) {
return document.getElementById(n);
}
function setInn(n, i) {
document.getElementById(n).innerHTML = i;
}
function processFiles(files) {
var file = files[0];
var reader = new FileReader();
srcImg = new Image();
reader.onload = function (e) {
setInn('srcBox', '<img id="imgView" class="sourceImage">');
var img = getElm('imgView');
img.src = e.target.result;
srcImg.src = e.target.result;
};
reader.readAsDataURL(file);
}
function drop(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files;
processFiles(files);
}
function ignoreDrag(e) {
e.stopPropagation();
e.preventDefault();
}
function getNud(nm, vl) {
return '<td class="comment">' + nm + ':</td>' +
'<td><input id="nud_' + nm + '" class="nud"type="number" value="' + vl + '"/></td>';
}
function Btn(nm, tx, fn) {
return '<div><label class="menu_button" for="_' + nm + '">' + tx + '</label>' +
'<input class="hidden_input" id="_' + nm + '" type="' +
(nm == 0 ? 'file" onchange="' : 'button" onclick="') + fn + '"/></div>';
}
function RB(vl, tx) {
return '<input type="radio" name="kind" value="m' + vl +
'" onclick="rbClick(' + vl + ');"' + (vl == 0 ? 'checked="true"' : '') + '/>' + tx;
}
window.onload = function () {
srcBox = getElm('srcBox');
srcBox.ondragenter = ignoreDrag;
srcBox.ondragover = ignoreDrag;
srcBox.ondrop = drop;
srcImg = 0;
epdInd = 0;
palArr = [[[0, 0, 0], [255, 255, 255]],
[[0, 0, 0], [255, 255, 255], [127, 0, 0]],
[[0, 0, 0], [255, 255, 255], [127, 127, 127]],
[[0, 0, 0], [255, 255, 255], [127, 127, 127], [127, 0, 0]],
[[0, 0, 0], [255, 255, 255]],
[[0, 0, 0], [255, 255, 255], [220, 180, 0]],
[[0, 0, 0]],
[[0, 0, 0], [255, 255, 255], [0, 255, 0], [0, 0, 255], [255, 0, 0], [255, 255, 0], [255, 128, 0]]];
epdArr = [[200, 200, 0], [200, 200, 3], [152, 152, 5],
[122, 250, 0], [104, 212, 1], [104, 212, 5], [104, 212, 0],
[176, 264, 0], [176, 264, 1],
[128, 296, 0], [128, 296, 1], [128, 296, 5], [128, 296, 0],
[400, 300, 0], [400, 300, 1], [400, 300, 5],
[600, 448, 0], [600, 448, 1], [600, 448, 5],
[640, 384, 0], [640, 384, 1], [640, 384, 5],
[800, 480, 0], [800, 480, 1], [880, 528, 1],
[600, 448, 7], [880, 528, 0], [280, 480, 0],
[152, 296, 0], [648, 480, 1], [128, 296, 1],
[200, 200, 1], [104, 214, 1], [128, 296, 0],
[400, 300, 1], [152, 296, 1], [648, 480, 0],
[640, 400, 7], [176, 264, 1], [122, 250, 0],
[122, 250, 1], [240, 360, 0], [176, 264, 0],
[122, 250, 0], [400, 300, 0], [960, 680, 0],
[800, 480, 0], [128, 296, 1], [960, 680, 1]];
setInn('BT',
Btn(0, 'Select image file', 'processFiles(this.files);') +
Btn(1, 'Level: mono', 'procImg(true,false);') +
Btn(2, 'Level: color', 'procImg(true,true);') +
Btn(3, 'Dithering: mono', 'procImg(false,false);') +
Btn(4, 'Dithering: color', 'procImg(false,true);') +
Btn(5, 'Upload image', 'uploadImage();'));
setInn('XY', getNud('x', '0') + getNud('y', '0'));
setInn('WH', getNud('w', '200') + getNud('h', '200'));
setInn('RB', RB(0, '1.54  ') + RB(1, '1.54b') + RB(2, '1.54c <br>') +
RB(3, '2.13 ') + RB(4, '2.13b') + RB(5, '2.13c<br>') +
RB(6, '2.13d') + RB(7, '2.7  ') + RB(8, '2.7b <br>') +
RB(9, '2.9  ') + RB(10, '2.9b ') + RB(11, '2.9c <br>') +
RB(12, '2.9d ') + RB(13, '4.2  ') + RB(14, '4.2b <br>') +
RB(15, '4.2c ') + RB(16, '5.83 ') + RB(17, '5.83b<br>') +
RB(18, '5.83c ') + RB(19, '7.5  ') + RB(20, '7.5b<br>') +
RB(21, '7.5c') + RB(22, '7.5 V2') + RB(23, '7.5b-V2<br>') +
RB(24, '7.5b HD ') + RB(25, '5.65f<br>') +
RB(26, '7.5 HD ') + RB(27, '3.7 ') + RB(28, '2.66<br>') +
RB(29, '5.83b V2 ') + RB(30, '2.9b V3<br>') +
RB(31, '1.54b V2 ') + RB(32, '2.13b V3<br>') +
RB(33, '2.9 V2 ') + RB(34, '4.2b V2<br>') +
RB(35, '2.66b ') + RB(36, '5.83 V2<br>') +
RB(37, '4.01 f ') + RB(38, '2.7b V2<br>') +
RB(39, '2.13 V3 ') + RB(40, '2.13 B V4<br>') +
RB(41, '3.52 ') + RB(42, '2.7 V2<br>') +
RB(43, '2.13 V4 ') + RB(44, '4.2 V2<br>') +
RB(45, '13.3k ') + RB(46, '4.26<br>') +
RB(47, '2.9bV4 ') + RB(48, '13.3b<br>'));
}
function rbClick(index) {
getElm('nud_w').value = +epdArr[index][0];
getElm('nud_h').value = +epdArr[index][1];
epdInd = index;
}
</script>
<script type="text/javascript">
var source;
var dX, dY, dW, dH, sW, sH;
function getVal(p, i) {
if ((p.data[i] == 0x00) && (p.data[i + 1] == 0x00)) return 0;
if ((p.data[i] == 0xFF) && (p.data[i + 1] == 0xFF)) return 1;
if ((p.data[i] == 0x7F) && (p.data[i + 1] == 0x7F)) return 2;
return 3;
}
function getVal_7color(p, i) {
if ((p.data[i] == 0x00) && (p.data[i + 1] == 0x00) && (p.data[i + 2] == 0x00)) return 0;
if ((p.data[i] == 0xFF) && (p.data[i + 1] == 0xFF) && (p.data[i + 2] == 0xFF)) return 1;
if ((p.data[i] == 0x00) && (p.data[i + 1] == 0xFF) && (p.data[i + 2] == 0x00)) return 2;
if ((p.data[i] == 0x00) && (p.data[i + 1] == 0x00) && (p.data[i + 2] == 0xFF)) return 3;
if ((p.data[i] == 0xFF) && (p.data[i + 1] == 0x00) && (p.data[i + 2] == 0x00)) return 4;
if ((p.data[i] == 0xFF) && (p.data[i + 1] == 0xFF) && (p.data[i + 2] == 0x00)) return 5;
if ((p.data[i] == 0xFF) && (p.data[i + 1] == 0x80) && (p.data[i + 2] == 0x00)) return 6;
return 7;
}
function setVal(p, i, c) {
p.data[i] = curPal[c][0];
p.data[i + 1] = curPal[c][1];
p.data[i + 2] = curPal[c][2];
p.data[i + 3] = 255;
}
function addVal(c, r, g, b, k) {
return [c[0] + (r * k) / 32, c[1] + (g * k) / 32, c[2] + (b * k) / 32];
}
function getErr(r, g, b, stdCol) {
r -= stdCol[0];
g -= stdCol[1];
b -= stdCol[2];
return r * r + g * g + b * b;
}
function getNear(r, g, b) {
var ind = 0;
var err = getErr(r, g, b, curPal[0]);
for (var i = 1; i < curPal.length; i++) {
var cur = getErr(r, g, b, curPal[i]);
if (cur < err) { err = cur; ind = i; }
}
return ind;
}
</script>
<script type="text/javascript">
function procImg(isLvl, isRed) {
if (document.getElementsByClassName('sourceImage').length == 0) {
alert('First select image');
return;
}
var palInd = epdArr[epdInd][2];
if (isRed && ((palInd & 1) == 0)) {
alert('This white-black display');
return;
}
if (!isRed) palInd = palInd & 0xFE;
curPal = palArr[palInd];
getElm('dstBox').innerHTML =
'<span class="title">Processed image</span><br><canvas id="canvas"></canvas>';
var canvas = getElm('canvas');
sW = srcImg.width;
sH = srcImg.height;
source = getElm('source');
source.width = sW;
source.height = sH;
source.getContext('2d').drawImage(srcImg, 0, 0, sW, sH);
dX = parseInt(getElm('nud_x').value);
dY = parseInt(getElm('nud_y').value);
dW = parseInt(getElm('nud_w').value);
dH = parseInt(getElm('nud_h').value);
if ((dW < 3) || (dH < 3)) {
alert('Image is too small');
return;
}
canvas.width = dW;
canvas.height = dH;
var index = 0;
var pSrc = source.getContext('2d').getImageData(0, 0, sW, sH);
var pDst = canvas.getContext('2d').getImageData(0, 0, dW, dH);
if (isLvl) {
for (var j = 0; j < dH; j++) {
var y = dY + j;
if ((y < 0) || (y >= sH)) {
for (var i = 0; i < dW; i++, index += 4) setVal(pDst, index, (i + j) % 2 == 0 ? 1 : 0);
continue;
}
for (var i = 0; i < dW; i++) {
var x = dX + i;
if ((x < 0) || (x >= sW)) {
setVal(pDst, index, (i + j) % 2 == 0 ? 1 : 0);
index += 4;
continue;
}
var pos = (y * sW + x) * 4;
setVal(pDst, index, getNear(pSrc.data[pos], pSrc.data[pos + 1], pSrc.data[pos + 2]));
index += 4;
}
}
} else {
var aInd = 0;
var bInd = 1;
var errArr = new Array(2);
errArr[0] = new Array(dW);
errArr[1] = new Array(dW);
for (var i = 0; i < dW; i++)
errArr[bInd][i] = [0, 0, 0];
for (var j = 0; j < dH; j++) {
var y = dY + j;
if ((y < 0) || (y >= sH)) {
for (var i = 0; i < dW; i++, index += 4)setVal(pDst, index, (i + j) % 2 == 0 ? 1 : 0);
continue;
}
aInd = ((bInd = aInd) + 1) & 1;
for (var i = 0; i < dW; i++)errArr[bInd][i] = [0, 0, 0];
for (var i = 0; i < dW; i++) {
var x = dX + i;
if ((x < 0) || (x >= sW)) {
setVal(pDst, index, (i + j) % 2 == 0 ? 1 : 0);
index += 4;
continue;
}
var pos = (y * sW + x) * 4;
var old = errArr[aInd][i];
var r = pSrc.data[pos] + old[0];
var g = pSrc.data[pos + 1] + old[1];
var b = pSrc.data[pos + 2] + old[2];
var colVal = curPal[getNear(r, g, b)];
pDst.data[index++] = colVal[0];
pDst.data[index++] = colVal[1];
pDst.data[index++] = colVal[2];
pDst.data[index++] = 255;
r = (r - colVal[0]);
g = (g - colVal[1]);
b = (b - colVal[2]);
if (i == 0) {
errArr[bInd][i] = addVal(errArr[bInd][i], r, g, b, 7.0);
errArr[bInd][i + 1] = addVal(errArr[bInd][i + 1], r, g, b, 2.0);
errArr[aInd][i + 1] = addVal(errArr[aInd][i + 1], r, g, b, 7.0);
} else if (i == dW - 1) {
errArr[bInd][i - 1] = addVal(errArr[bInd][i - 1], r, g, b, 7.0);
errArr[bInd][i] = addVal(errArr[bInd][i], r, g, b, 9.0);
} else {
errArr[bInd][i - 1] = addVal(errArr[bInd][i - 1], r, g, b, 3.0);
errArr[bInd][i] = addVal(errArr[bInd][i], r, g, b, 5.0);
errArr[bInd][i + 1] = addVal(errArr[bInd][i + 1], r, g, b, 1.0);
errArr[aInd][i + 1] = addVal(errArr[aInd][i + 1], r, g, b, 7.0);
}
}
}
}
canvas.getContext('2d').putImageData(pDst, 0, 0);
}
</script>
<script type="text/javascript">
var pxInd, stInd;
var dispW, dispH;
var xhReq, dispX;
var rqPrf, rqMsg;
function byteToStr(v) { return String.fromCharCode((v & 0xF) + 97, ((v >> 4) & 0xF) + 97); }
function wordToStr(v) { return byteToStr(v & 0xFF) + byteToStr((v >> 8) & 0xFF); }
function u_send(cmd, next) {
/* 配置POST请求,异步模式(第三个参数) */
xhReq.open('POST', rqPrf + cmd, true);
xhReq.send('');
if (next)
stInd++;
return 0;
}
function u_next() {
lnInd = 0;
pxInd = 0;
u_send('NEXT_', true);
}
function u_done() {
setInn('logTag', 'Complete!');
return u_send('SHOW_', true);
}
function u_show(a, k1, k2) { var x = '' + (k1 + k2 * pxInd / a.length); if (x.length > 5) x = x.substring(0, 5); setInn('logTag', 'Progress: ' + x + '%'); return u_send(rqMsg + wordToStr(rqMsg.length) + 'LOAD_', pxInd >= a.length); }
function u_data(a, c, k1, k2) {
rqMsg = '';
if (c == -1) {
while ((pxInd < a.length) && (rqMsg.length < 1000)) {
var v = 0;
for (var i = 0; i < 16; i += 2)if (pxInd < a.length) v |= (a[pxInd++] << i);
rqMsg += wordToStr(v);
}
}
else if (c == -2) {
while ((pxInd < a.length) && (rqMsg.length < 1000)) {
var v = 0;
for (var i = 0; i < 16; i += 4)if (pxInd < a.length) v |= (a[pxInd++] << i);
rqMsg += wordToStr(v);
}
}
else {
while ((pxInd < a.length) && (rqMsg.length < 1000)) {
var v = 0;
for (var i = 0; i < 8; i++) if ((pxInd < a.length) && (a[pxInd++] != c)) v |= (128 >> i);
rqMsg += byteToStr(v);
}
}
return u_show(a, k1, k2);
}
function u_line(a, c, k1, k2) {
var x;
rqMsg = '';
while (rqMsg.length < 1000) {
x = 0;
while (x < 122) {
var v = 0;
for (var i = 0; (i < 8) && (x < 122); i++, x++) if (a[pxInd++] != c) v |= (128 >> i);
rqMsg += byteToStr(v);
}
}
return u_show(a, k1, k2);
}
function uploadImage() {
var c = getElm('canvas');
var w = dispW = c.width;
var h = dispH = c.height;
var p = c.getContext('2d').getImageData(0, 0, w, h);
var a = new Array(w * h);
var i = 0;
for (var y = 0; y < h; y++)for (var x = 0; x < w; x++, i++) {
if (epdInd == 25 || epdInd == 37)
a[i] = getVal_7color(p, i << 2);
else
a[i] = getVal(p, i << 2);
}
dispX = 0;
pxInd = 0;
stInd = 0;
xhReq = new XMLHttpRequest();
rqPrf = 'http://' + getElm('ip_addr').value + '/';
if ((epdInd == 3) || (epdInd == 39) || (epdInd == 43)) {
xhReq.onload = xhReq.onerror = function () {
if (stInd == 0) return u_line(a, 0, 0, 100);
if (stInd == 1) return u_done();
};
if (epdInd > 25)
return u_send('EPD' + String.fromCharCode(epdInd + -26 + 65) + '_', false);
return u_send('EPD' + String.fromCharCode(epdInd + 97) + '_', false);
}
if ((epdInd == 40)) {
xhReq.onload = xhReq.onerror = function () {
if (stInd == 0) return u_line(a, 0, 0, 50);
if (stInd == 1) return u_next();
if (stInd == 2) return u_line(a, 3, 50, 50);
if (stInd == 3) return u_done();
};
if (epdInd > 25)
return u_send('EPD' + String.fromCharCode(epdInd + -26 + 65) + '_', false);
return u_send('EPD' + String.fromCharCode(epdInd + 97) + '_', false);
}
if ((epdInd == 0) || (epdInd == 3) || (epdInd == 6) || (epdInd == 7) || (epdInd == 9) || (epdInd == 12) || (epdInd == 16) || (epdInd == 19) || (epdInd == 22) || (epdInd == 26) || (epdInd == 27) || (epdInd == 28)) {
xhReq.onload = xhReq.onerror = function () {
if (stInd == 0)
return u_data(a, 0, 0, 100);
if (stInd == 1)
return u_done();
};
if (epdInd > 25)
return u_send('EPD' + String.fromCharCode(epdInd + -26 + 65) + '_', false);
return u_send('EPD' + String.fromCharCode(epdInd + 97) + '_', false);
}
if (epdInd > 15 && epdInd < 22) {
xhReq.onload = xhReq.onerror = function () {
if (stInd == 0)
return u_data(a, -1, 0, 100);
if (stInd == 1)
return u_done();
};
return u_send('EPD' + String.fromCharCode(epdInd + 97) + '_', false);
}
if (epdInd == 25 || epdInd == 37) {
xhReq.onload = xhReq.onerror = function () {
if (stInd == 0)
return u_data(a, -2, 0, 100);
if (stInd == 1)
return u_done();
};
if (epdInd > 25)
return u_send('EPD' + String.fromCharCode(epdInd + -26 + 65) + '_', false);
return u_send('EPD' + String.fromCharCode(epdInd + 97) + '_', false);
}
else {
xhReq.onload = xhReq.onerror = function () {
console.log('*************');
console.log(stInd);
console.log('*************');
if (stInd == 0 && epdInd == 23)
return u_data(a, 0, 0, 100);
if (stInd == 0)
return u_data(a, ((epdInd == 1) || (epdInd == 12)) ? -1 : 0, 0, 50);
if (stInd == 1)
return u_next();
if (stInd == 2)
return u_data(a, 3, 50, 50);
if (stInd == 3)
return u_done();
};
if (epdInd > 25)
return u_send('EPD' + String.fromCharCode(epdInd + -26 + 65) + '_', false);
return u_send('EPD' + String.fromCharCode(epdInd + 97) + '_', false);
}
}
</script>
<table class="fixed" border="20">
<col width="80%" />
<tr>
<td>
<table border="2">
<tr>
<td>
<h3>ESP32 File Server</h3>
</td>
</tr>
<tr>
<td>
<label for="newfile">Upload a file</label>
</td>
<td colspan="2">
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
</td>
</tr>
<tr>
<td style="width:30%;">
<label for="filepath">Set path on server</label>
</td>
<td style="width:50%;">
<input id="filepath" type="text" style="width:100%;">
</td>
<td style="width:20%;">
<button id="upload" type="button" onclick="upload()">Upload</button>
</td>
</tr>
</table>
</td>
</tr>
</table>
<div class="header_back">
<div class="header_face"></div>
</div>
<div class="content_back">
<div class="content_face">
<table style="width:100%; height:100%" border="0" cellspacing="0">
<tr>
<td class="menu_bar" rowspan="2">
<div id="BT"></div>
<table>
<tr>
<td class="comment" colspan="4">
<br>Device IP:
</td>
</tr>
<tr>
<td colspan="4">
<input id="ip_addr" style="width:100%;text-align:center" type="text"
value="192.168.1.211">
</td>
</tr>
<tr>
<td class="comment" colspan="4">
<br>Bounds:
</td>
</tr>
<tr id="XY"></tr>
<tr id="WH"></tr>
</table>
<div id="RB"></div>
</td>
<td class="content_body">
<span class="title">Original image</span>
<br>
<canvas id="source" class="hidden_input"></canvas>
<div id="srcBox">
<div class="imgBox">
<div class="mesBox">Drop image here...</div>
</div>
</div>
</td>
</tr>
<tr>
<td id="dstBox" class="content_body"></td>
</tr>
</table>
</div>
</div>
<div class="footer_back">
<div class="footer_face" id="logTag"></div>
</div>
<script>
function setpath() {
var default_path = document.getElementById("newfile").files[0].name;
document.getElementById("filepath").value = default_path;
}
function upload() {
/* 执行6个验证条件(文件选择、路径设置、空格检查、路径结尾、文件大小) */
const fileInput = document.getElementById("newfile").files;
const filePath = document.getElementById("filepath").value.trim();
const upload_path = "/upload/" + filePath;
// alert(upload_path);
/* Max size of an individual file. Make sure this value is same as that set in file_server.c */
var MAX_FILE_SIZE = 200 * 1024;
var MAX_FILE_SIZE_STR = "200KB";
if (fileInput.length == 0) {
alert("No file selected!");
} else if (filePath.length == 0) {
alert("File path on server is not set!");
} else if (filePath.indexOf(' ') >= 0) {
alert("File path on server cannot have spaces!");
} else if (filePath[filePath.length - 1] == '/') {
alert("File name not specified after path!");
} else if (fileInput[0].size > 200 * 1024) {
alert("File size must be less than 200KB!");
} else {
/* 禁用表单元素 */
document.getElementById("newfile").disabled = true;
document.getElementById("filepath").disabled = true;
document.getElementById("upload").disabled = true;
/* 通过传统 XMLHttpRequest 实现文件上传功能 */
var file = fileInput[0];
var xhttp = new XMLHttpRequest();
/* 设置请求状态变更时的回调函数 */
xhttp.onreadystatechange = function () {
/* 检查请求是否完成 */
if (xhttp.readyState == 4) {
/* 检查HTTP状态码是否为200(成功) */
if (xhttp.status == 200) {
/* 打开当前文档(准备写入) */
document.open();
/* 将服务器响应内容写入文档 */
document.write(xhttp.responseText);
/* 关闭文档写入模式 */
document.close();
/* 处理服务器主动关闭连接的情况 */
} else if (xhttp.status == 0) {
alert("Server closed the connection abruptly!");
location.reload()
} else {
alert(xhttp.status + " Error!\n" + xhttp.responseText);
location.reload()
}
}
};
/* 配置POST请求,异步模式(第三个参数) */
xhttp.open("POST", upload_path, true);
xhttp.send(file);
}
}
</script>
更多推荐
所有评论(0)