Load html site (made of multiple file) from SD

Hi everybody

I've some problem trying to load a "Site" made of several files (home.htm + style.css + xxx.js ecc.)
I load the hp page -> htmlFile = SD.open("home.htm");
but all the link contained (style.css xxx.js) doesn't start

Help me please....

1 Like

Help me please....

You need to go first. Post the code that you are using, and any sample output that are seeing.

Here the code

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 10, 172, 80, 203 };           // ip in lan
String readString = String(30); //string for fetching data from address
File htmlFile;
EthernetServer server(80);

void setup()
{
  
  Ethernet.begin(mac, ip);
    Serial.begin(9600);
  server.begin();
  if (!SD.begin(4)) { return; }

}
 

void loop()
{
 
   EthernetClient client = server.available(); // Create a client connection

  if (client) {
        
    boolean currentLineIsBlank = true;

     
    while (client.connected()) 
    {

      if (client.available()) 
      {
        char c = client.read();
        
        if (readString.length() < 100)
        {
         
          readString += c; 
             
        }
          if (c == '\n') 
          {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
   
            htmlFile = SD.open("home.htm");
            if (htmlFile) 
            {
              while (htmlFile.available()) 
              {
                client.write(htmlFile.read());
              }
  
              htmlFile.close();            // close the file:
            }
              break;
              
          } 
       
      }
      
    } 
  
     readString="";
    
        client.stop();
        delay(1);
  }
}

and then the home.html file (see the css & JS file actually stored in the same home.htm directory )

<!-- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -->
<html>

<head>

	<title>a blog</title>
	<link rel="stylesheet" type="text/css" href="stile.css" />
	<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Michroma" />
	
</head>


<body>

<div id="pagina">


		<script type="text/javascript" src="template.js"></script>
	
	<div id="corpo-centrale"class="sinistra" align=justify>
			
			Choose item to test....
			

	</div>
	
	<div id="colonna-dx" class="sinistra">
		<!-- null -->

	
</div>

	</div>
	
	
	
	<script type="text/javascript" src="footer.js"></script>
	
</body>

see the css & JS file actually stored in the same home.htm directory

And the relevance of this statement is?

You can't expect them to get magically sent to the client. You must make that happen. All I see you sending is the home.htm file.

Printing the data that comes from the client is a good idea. If the client is requesting home.htm, and you send home.htm, great. If the client is then requesting stile.css file, and you respond with the home.htm file, that hardly satisfies the client's request. The same problem exists if you send home.htm is response to a request for template.js.

So, what IS the client asking for?

hope this will be helpful to get you started.

this is a sample program that currently only serves htm and jpg files. you can modify it to serve css, js, and what not. Just remember the SD file system only recognized 8.3 filenames. This is not a problem because you can always map incoming long filenames to the real 8.3 filename.
for this example, you need to save the attached index.htm and uno.jpg file to your SD card. For your case, you need to put all your css, js, etc files in the SD after you modify this code to recognize those filename extensions and respond with the correct MIME type header (e.g. text/css for css file, text/javascript for js file). I'll let you do the modification (hint, add more else if statements), but I can guarantee you what you want to do will work.

This example also uses buffered reads and writes to improve performance.

/*
 A simple web server with microSD using an Arduino Wiznet Ethernet shield. 
 For Arduino IDE V1.0 only. Earlier IDEs require mods to this code.  
 created 18 Dec 2009
 by David A. Mellis
 modified 4 Sep 2010
 by Tom Igoe
 modified 14 Jan 2012
 by Tim Dicus
modified 5 Mar 2012
 by Jerry Sy aka doughboy
*/
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and network settings for your controller below.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 192,168,1,17 );
//IPAddress gateway( 192,168,1,1 );
//IPAddress dns( 1,2,3,4 );
//IPAddress subnet( 255,255,255,0 );

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

char buffer[64];
int index = 0;

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

  // Set SS pins for both w5100 and microSD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);
  
  // Start microSD.
  // This disables the SD SPI interface before returning
  SD.begin(4);

  // start the Ethernet connection and the server:
  // This leaves the w5100 SPI enabled
  if (Ethernet.begin(mac) == 0) {
    Ethernet.begin(mac, ip);
  }
  // disable w5100 SPI
  digitalWrite(10,HIGH);
  // now you can read/write to both w5100 and SD without manipulating the SS pins.

  delay(2000);
  server.begin();
//  Serial.println("Setup finished");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Client!");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      while(client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          Serial.println("sending response");
          // send a standard http response
          String s = buffer;
          String t;
          int idx = 0;
          if (s.startsWith("GET")) {
             client.println("HTTP/1.0 200 OK");
             if ((idx=s.indexOf(".htm"))>0  ) {
                 client.println("Content-Type: text/html");
             } else if ((idx=s.indexOf(".jpg"))>0) {
                 client.println("Content-Type: image/jpeg");               
             }
             t = s.substring(5,idx+5);
             client.println();
             sdCheck(client, t);
          }
          client.stop();
        }
        else if (c == '\r') {
          // you're starting a new line
          currentLineIsBlank = true;
          buffer[index]='\0';
          index=0;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
          buffer[index++] = c;
        }
      }
    }
    Serial.println("Client disconnected.");
  }
}

void sdCheck(EthernetClient client, String file)
{
  char filename[13];
  file.toCharArray(filename, file.length());
  File myFile = SD.open(filename);

  if (myFile) {
    Serial.print("sending ");
    Serial.println(file);
    byte buffer[64];
    int count = 0;
    if (myFile.available()) {
      while ((count=myFile.read(buffer,64))> 0 ) {
        client.write(buffer,count);
      } 
    }
    // close the file:
    myFile.close();
  } else {
    client.println("ERROR");
  }
}

index.htm (145 Bytes)

uno.jpg

Thanks all guys....
@doughboy: very useful and clear code/explanation
@PaulS: thanks to let me thinking on ...