You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在Arduino内置本地网页中引入外部CSS文件(含SD卡存储)?

在Arduino以太网盾本地网页中引入外部CSS的正确方法

嘿,我完全懂你遇到的问题——直接在HTML里加<link>引用本地CSS根本没效果,对吧?这是因为Arduino的WebServer可不是电脑上的专业服务器,它不会自动帮你处理静态文件请求,得我们自己写代码来响应浏览器对CSS的请求才行。

下面给你两种经过验证的可行方案,都是我做类似项目时用过的:

方案一:将CSS嵌入代码,响应/style.css请求

这是最直接的方法,把CSS内容写成字符串存到Arduino代码里,当浏览器请求/style.css时,服务器返回这个CSS内容和正确的响应头。

完整代码示例

#include <Ethernet.h>

// 替换成你的MAC地址和局域网IP
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);

// 用Raw String Literal写CSS,不用转义引号,写起来超省心
const char* css = R"=====(
body {
  background-color: #f0f0f0;
  font-family: Arial, sans-serif;
  margin: 20px;
}
.sensor-card {
  background: white;
  padding: 25px;
  border-radius: 10px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.1);
  max-width: 400px;
  margin: 0 auto;
}
.sensor-card h1 {
  color: #2c3e50;
  margin-top: 0;
}
.sensor-value {
  font-size: 1.2em;
  margin: 10px 0;
  color: #34495e;
}
)=====";

void setup() {
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.begin(9600);
  delay(1000);
  Serial.print("Server running at ");
  Serial.println(ip);
}

void loop() {
  EthernetClient client = server.available();
  if (client) {
    // 读取浏览器的请求内容
    String request = client.readStringUntil('\r');
    Serial.println(request);
    client.flush();

    // 处理CSS文件请求
    if (request.indexOf("GET /style.css") != -1) {
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/css"); // 这个响应头必须正确,浏览器才会识别为CSS
      client.println("Connection: close");
      client.println();
      client.println(css);
    }
    // 处理主页请求
    else if (request.indexOf("GET /") != -1) {
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("Connection: close");
      client.println();
      // 网页结构里正常引用/style.css
      client.println("<!DOCTYPE html>");
      client.println("<html>");
      client.println("<head>");
      client.println("<link rel='stylesheet' href='/style.css'>");
      client.println("<title>Accelerometer Data</title>");
      client.println("</head>");
      client.println("<body>");
      client.println("<div class='sensor-card'>");
      client.println("<h1>Accelerometer Readings</h1>");
      // 替换成你的加速度传感器读取逻辑
      client.println("<p class='sensor-value'>X: " + String(analogRead(A0)) + "</p>");
      client.println("<p class='sensor-value'>Y: " + String(analogRead(A1)) + "</p>");
      client.println("<p class='sensor-value'>Z: " + String(analogRead(A2)) + "</p>");
      client.println("</div>");
      client.println("</body>");
      client.println("</html>");
    }

    delay(1);
    client.stop();
  }
}

关键要点

  • 必须处理CSS请求:浏览器加载网页时会单独发起/style.css的请求,我们的代码要检测到这个请求并返回正确响应,尤其是Content-Type: text/css这个头,少了它浏览器会把CSS当成普通文本,不会生效。
  • Raw String Literal语法:用R"=====(...)====="包裹CSS内容,不用转义里面的双引号,编写复杂CSS时特别方便。

方案二:用PROGMEM存储CSS(适合长CSS,节省RAM)

如果你的CSS内容比较长,直接存在RAM里会占用Arduino宝贵的内存空间,这时候可以把CSS存在程序存储器(PROGMEM)里,读取时再取出来。

修改后的关键代码

#include <avr/pgmspace.h>

// 把CSS存在PROGMEM里
const char css[] PROGMEM = R"=====(
/* 这里是你的长CSS内容 */
)=====";

// 处理CSS请求时的返回逻辑
if (request.indexOf("GET /style.css") != -1) {
  client.println(F("HTTP/1.1 200 OK"));
  client.println(F("Content-Type: text/css"));
  client.println(F("Connection: close"));
  client.println();
  // 从PROGMEM读取并打印CSS
  char buffer[128];
  strcpy_P(buffer, css);
  client.println(buffer);
  // 如果CSS太长,需要循环分段读取,避免buffer溢出
}

常见坑点提醒

  1. 不要引用电脑上的CSS文件:Arduino运行时是独立设备,根本访问不到你电脑草图目录里的文件,必须把CSS内容嵌入代码或者存在SD卡(如果使用了SD模块)。
  2. 浏览器缓存问题:修改CSS后如果没生效,试试按Ctrl+F5强制刷新浏览器,清除缓存。
  3. 局域网连接检查:确保你的电脑和Arduino在同一个WiFi/局域网里,并且Arduino的IP地址设置正确。

内容的提问来源于stack exchange,提问作者Dylan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:11:39