In this tutorial we will check how to serve the jQuery source file from the ESP32 and develop a very simple web page that makes use of it.
For this tutorial we will be using the Arduino core and the HTTP async web server libraries. Due to the size of the files, we will be serving them from the ESP32 SPIFFS file system. You can check in more detail how to do it on this previous tutorial.
In order to make it easier to upload the files to the ESP32 file system, we will make use of this plugin for the Arduino IDE.
The tests of this ESP32 tutorial were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.
jQuery is a JavaScript library that makes it easier to manipulate the HTML DOM and handling events and Ajax [1], amongst other features. So, it is a useful tool that many web developers use when building applications.
Naturally, in order for a JavaScript application to use this library, its source code needs to somehow be included. When developing a web application, we can include external JavaScript files using the HTML script tag and its src attribute.
Nonetheless, some entity needs to make the source code of the jQuery library available to be fetched by the client application that will render the HTML page. If we are sure that the machine that is going to be running the code has access to the Internet, then the jQuery source can be retrieved from a remote server or from a public Content Distribution Network (CDN). You can check here the CDN for jQuery.
Nonetheless, when it comes to Internet of Things development, there are use cases when it may be needed to present a web page to the user before the device is connected to the Internet (this can be done with the device operating as soft AP, for example). In that case, we cannot rely on a remote server to serve any dependencies we have. So, if our application uses a framework such as jQuery, it needs to be served by the device.
In this tutorial, we will check how to serve the jQuery library from the ESP32, which allows to develop applications that rely on this library without depending on an Internet connection.
To get started, we need to download the jQuery compressed source file from here, as shown in figure 1. As can be seen, I’ve used version 3.3.1.
Figure 1 – Downloading the compressed version of jQuery.
Note that if you open the downloaded file you will see a lot of code without any formatting, which will not be easily readable for a person. Nonetheless, browsers don’t care about formatting and can read the file it that compressed format.
So, removing all the unnecessary tabs, new lines and empty spaces leads to a much smaller file. This means that there’s less data to send over the network, which means faster speed and more performance. In our case, besides that, it means much less space occupied in the ESP32 file system, which is of extreme importance since this is a resource constrained device.
If you want to take a look at the source code of jQuery you can download the uncompressed version from the same link. Note however that you should not use it in production environments for the mentioned reasons.
Now that we have the jQuery source file, we need to upload it to the ESP32. To do it, we will use the Arduino IDE plugin covered in this tutorial.
In short, we need to navigate to the Arduino sketch folder and there create a folder named “data“. Inside that folder, we should put the jQuery source file and the HTML file that will make use of this library (we will cover its code below). This is illustrated in figure 2.
Figure 2 – Data folder with the jQuery and HTML files.
Note: to keep things simple we are not covering here the compression of our HTML file, but the same principle mentioned before also applies. So, to save some space in the ESP32 and optimize the serving of the file, you should minify it in a final application. There are lots tools available to do it.
After having the files in the data folder and assuming that you have already installed the mentioned Arduino IDE file upload plugin, simply go to Tools and click “ESP32 Sketch Data Upload“.
After the procedure finishes, both files should be available at the root of the ESP32 file system with the names they had on the computer from which they were uploaded.
So, we should have a file with the path “/jquery-3.3.1.min.js” and another with the path “/test.html”. Note that I’ve called the HTML file test.html, but you can use another name, as long as you pass the correct value in the Arduino code shown below.
The code we are going to develop will be very simple since our aim with this tutorial is to show that it is possible to serve the jQuery source file from the ESP32 and not to focus too much on actual coding using this framework.
So, our simple example will consist on a paragraph and a button that, when clicked, hides the paragraph using some jQuery functions.
In terms of jQuery, we will make use of this framework inside a JavaScript function, the one that will be called when the mentioned button is clicked. We will call our function hide.
In our function implementation, we will use the jQuery ID selector to access a HTML element, more precisely, the paragraph we have mentioned. We are going to assume that the paragraph will have an ID equal to “paragraph“.
Then, we will use the jQuery hide method to hide the HTML element. We will pass as input an optional parameter which indicates the duration of the hiding animation. This value is specified in milliseconds and we will use the value 2000, so the paragraph will fade away instead of immediately disappearing.
function hide() { $("#paragraph").hide(2000); }
Regarding the full HTML code, the previous function will be enclosed in a script tag on the head section.
We will also have an additional script tag pointing to the external jQuery file, so the the functionalities of this framework can be used. In this case, we need to use the src attribute of the script tag to indicate the name of the file to be fetched.
Since the jQuery source file will be served by the same server that is serving this HTML code (our ESP32), we should use a relative path. In our case, it is simply the name of the file, as we will see when configuring the routes of the server on the Arduino code.
After the head section we will have the HTML elements on the body section, as shown below in the complete final code. As already pointed, the paragraph should have an ID equal to “paragraph̶#8221; and the button should invoke the hide function we have defined on our JavaScript script, when clicked.
<!DOCTYPE html> <html> <head> <script> function hide() { $("#paragraph").hide(2000); } </script> </head> <body> <p id="paragraph">Text to be hidden</p> <button onclick="hide()">Hide</button> </body> </html>
In terms of coding, this tutorial is very similar to what we have been done before when serving files from the file system.
So, we start by including the libraries needed. We need the WiFi.h to connect the ESP32 to a WiFi network, the SPIFFS.h to be able to serve files from the file system and the ESPAsyncWebServer.h so we can setup the web server.
Followed by that, we will need to declare the WiFi network credentials so the ESP32 can later connect to it.
To finalize the global variables declaration, we need an object of class AsyncWebServer, which will be used to setup the server.
#include "WiFi.h" #include "SPIFFS.h" #include "ESPAsyncWebServer.h" const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; AsyncWebServer server(80);
Moving on to the setup function, we perform the usual procedure. First we open the serial connection, then we initialize the file system and after that we connect the ESP32 to the WiFi network.
Serial.begin(115200); if(!SPIFFS.begin()){ Serial.println("An Error has occurred while mounting SPIFFS"); return; } WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Serial.println(WiFi.localIP());
Now we need to take care of setting the server routes. The first route we will configure is the one that will serve the HTML file. We will call that route “/html” and since the client will only fetch the HTML code, it should listen to HTTP GET requests.
The handling function will consist on returning back to the client the HTML file that we previously uploaded to the file system. To do it, we need to pass to the send method of the AsyncWebServerRequest the SPIFFS object and the path of the file as first and second arguments, respectively.
The SPIFFS object will be used under the hood by the web server framework to access the file. The complete path of the file is “/test.html”, as we have seen before.
As third and final argument of the send method we will pass a string with the content-type, which is “text/html“.
server.on("/html", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/test.html", "text/html"); });
We still need to declare a second route, which will be responsible for serving the jQuery source file. The route name will be the same as the file name: “/jquery-3.3.1.min.js”. Again, the route will only answer to HTTP GET requests, since no other HTTP method makes sense.
The handling function will also return back to the client the JQuery source file from the file system. So, again, we pass the SPIFFS object as first input of the send method and the complete path of the file as second. The complete path should be “/jquery-3.3.1.min.js”.
Finally, we will set the content-type to “text/javascript”. In this case the content-type is not “text/html” because we are only serving JavaScript code, which is different from having some JavaScript embedded on a HTML file.
server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/jquery-3.3.1.min.js", "text/javascript"); });
After that, we simply need to call the begin method on the server object, so it starts listening to incoming requests. After that, the server should be up and running. The final source code can be seen below.
#include "WiFi.h" #include "SPIFFS.h" #include "ESPAsyncWebServer.h" const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; AsyncWebServer server(80); void setup(){ Serial.begin(115200); if(!SPIFFS.begin()){ Serial.println("An Error has occurred while mounting SPIFFS"); return; } WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } Serial.println(WiFi.localIP()); server.on("/html", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/test.html", "text/html"); }); server.on("/jquery-3.3.1.min.js", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(SPIFFS, "/jquery-3.3.1.min.js", "text/javascript"); }); server.begin(); } void loop(){}
Assuming that you have already uploaded the files to the SPIFFS file system of the ESP32, simply compile and upload the Arduino code to the device. Once the procedure finishes, open the Arduino IDE serial monitor and copy the IP address that was printed after the connection to the WiFi network is established.
Then, open a web browser of your choice and type the following in the address bar, changing #yourIP# by the IP address you have just copied:
http://#yourIP#/html
To confirm that the jQuery file was loaded, you can open your web browser’s developer tools and check the requests made. Figure 3 shows the rendered web page and, on the right, the request made to fetch the jQuery source from the server.
Figure 3 – Serving jQuery from the ESP32.
If you click the “hide” button, then the paragraph should fade way, as described before.