The objective of this post is to explain how to access query parameters passed in HTTP requests sent to a web server deployed in the ESP8266.
Introduction
The objective of this post is to explain how to access query parameters passed in HTTP requests sent to a web server deployed in the ESP8266.
Query parameters appear at the end of the path of the URL [1] and allow to pass additional information. The query parameters compose the query string and are separated from the path in the URL by a question mark (“?”) [1].
Each query parameter is specified in the format “ParameterName=ParameterValue”. If multiple parameters need to be passed, they should be separated with ampersands (“&”) [1].
So, an example of a URL with query parameters is shown bellow.
http://website.com/path?parameter1=value1¶meter2=value2
This can be used to pass some extra information to the ESP8266, which can be read by the handling functions of the web server.
Note that, through this tutorial, the terms query parameter and argument are used with the same meaning when referring to the values passed in the URL.
The code
The initializing part of the code is pretty much the same as we analysed in the previous post about setting a HTTP server in the ESP8266, so only a brief summary will be presented. We start by connecting to the WiFi network and then we define in which URLs our HTTP web server will be listening to incoming requests.
For each URL, we specify the handling function that will execute upon a request on that URL.
In this specific case, we will define 2 URLs. In the first one, we will be able to receive any number of query parameters with any name and value. Then, our handling function will build and return a message with them. The name of this URL will be genericArgs. Notice the capital “A”, which needs to be taken in consideration when accessing the URL, since it will be case sensitive.
The other URL will also receive any number of query parameters, but will look for a specific parameter name and output a “not found” message when it is not present.
We will analyze the handling functions for this 2 URLs later. Now, we can see bellow the full code to initialize the HTTP web server.
#include <ESP8266WiFi.h> Â Â Â Â Â Â
#include <ESP8266WebServer.h>
ESP8266WebServer server(80); Â //Web server object. Will be listening in port 80 (default for HTTP)
void setup() {
Serial.begin(115200);
WiFi.begin(“YourSSID”, “YourPassword”); //Connect to the WiFi network
while (WiFi.status() != WL_CONNECTED) { //Wait for connection
delay(500);
Serial.println(“Waiting to connect…”);
}
Serial.print(“IP address: “);
Serial.println(WiFi.localIP()); Â //Print the local IP to access the server
server.on(“/genericArgs”, handleGenericArgs); //Associate the handler function to the path
server.on(“/specificArgs”, handleSpecificArg); Â Â //Associate the handler function to the path
server.begin(); Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â //Start the server
Serial.println(“Server listening”); Â Â
}
void loop() {
server.handleClient(); Â Â //Handling of incoming requests
}
Now we will analyse the code of the 2 handling functions for the URLs defined. Once again, the ESP8266WebServer library makes available easy to use functions to access the query parameters passed in the HTTP requests. The definition of the code of all the query parameter related functions is available here.
For the handler function that handles generic query parameters, we will first check how many of them were passed. To do so, we call the args method on the server object. This method will return the number of query parameters that were passed on the HTTP request that triggered the execution of the handling function.
String message = “Number of args received:”;
message += server.args();
Then, we will iterate by each parameter and print the name of the argument and the value.
We will use the argName method on the server object, which receives as a parameter an integer and will return the name of the argument in that position. The first query parameter is in position zero.
We will also use the arg method, which can also receive as a parameter an integer and returns the value of that parameter.
So, we build the for loop from 0 to the number of args – 1 (the first argument is in position zero) and append the name and value of the query parameter to our string.
for (int i = 0; i < server.args(); i++) {
message += “Arg nÂş” + (String)i + ” –> “;
message += server.argName(i) + “: “;
message += server.arg(i) + “\n”;
}Â
Finally, we return the message built using the send method on the server object, as we did in the previous post. We return it as “text/plan” and with a HTTP OK code.Â
server.send(200, “text/plain”, message);
The full code of the handling function is shown bellow.
void handleGenericArgs() { //Handler
String message = “Number of args received:”;
message += server.args(); Â Â Â Â Â Â //Get number of parameters
message += “\n”; Â Â Â Â Â Â Â Â Â Â Â Â Â Â //Add a new line
for (int i = 0; i < server.args(); i++) {
message += “Arg nÂş” + (String)i + ” –> “; Â //Include the current iteration value
message += server.argName(i) + “: “; Â Â //Get the name of the parameter
message += server.arg(i) + “\n”; Â Â Â Â Â Â Â //Get the value of the parameter
}Â
server.send(200, “text/plain”, message); Â Â Â //Response to the HTTP request
}
Now, we will specify the function that looks for a particular parameter name and prints its value if found. In this case, we will be looking for an argument with name “Temperature”. Once again, we need to take in consideration that the argument name is case sensitive and thus if we pass “temperature” as parameter it will not be considered.
We will again call the arg method mentioned before, but this time it will receive as input argument a string containing the name of the query parameter we want to find. If not found, the function will return an empty string (corresponding to “”). If found, the function will return the value of the query parameter.
So, in our code, we will call the arg method, look for the returning value and build the returning string accordingly, to include in the response to the request. Finally, we return the response to the HTTP  with the send method, as we did in the previous handling function. The code for the whole function is shown bellow.
void handleSpecificArg() {Â
String message = “”;
if (server.arg(“Temperature”)== “”){ Â Â //Parameter not found
message = “Temperature Argument not found”;
}else{ Â Â //Parameter found
message = “Temperature Argument = “;
message += server.arg(“Temperature”); Â Â //Gets the value of the query parameter
}
server.send(200, “text/plain”, message); Â Â Â Â Â //Returns the HTTP response
}
Important: When directly copying the code from the blog, a stray error may occur when trying to compile it on Arduino. In my case, this occurs because the editor assumes the wrong type of quotes. The easiest way to fix this, given the number of existing quotes, is to do a find and replace and put the correct quotes.
Final results
Once again, we can test our HTTP web server using a web browser such as Google Chrome. The first example, illustrated in figure 1, shows what happens when we access the “/genericArgs” URL without any query parameters.
Since we sent no parameters, the output indicates that the number of args received is zero.
Figure 1 – Result of accessing the /genericArgs URL without query parameters.
Figure 2 shows what happens if we access the same URL but now passing query parameters. In this case, we are sending 3 parameters, which represent a date. As can be seen, the output indicates that 3 args were received and then it lists the names and values of those args.
Figure 2 – Result of accessing the /genericArgs URL with 3 query parameters.
Figure 3 shows what happens if we access the /specificArg URL with a query parameter different from what we were looking for. In this case, we sent “Luminosity” instead of “Temperature”, so the answer to the HTTP request is that the “Temperature” argument is not found.
Figure 3Â – Result of accessing the /specificArgs URL with the wrong query parameter.
Finally, as shown in figure 4, when we call this URL sending the correct query parameter, our handling function recognizes it and returns its value.
Figure 4 – Result of accessing the /specificArgs URL with the right query parameter.
Related posts
References
[1]Â http://www.ronstauffer.com/blog/understanding-a-url/
Technical details
- ESP8266 libraries: v2.3.0
Não estou conseguindo achar o código completo. Alguém pode disponibilizar o mesmo ?
Boa noite,
Neste post não tenho nenhuma secção com o código completo. Na altura em que escrevi ainda não tinha o hábito de colocar o código completo no fim do artigo 🙂
No entanto, basta utilizar o primeiro bloco de código (que contem os includes de bibliotecas, o setup e o loop) e depois as duas definições das funções de handling das rotas, que se encontram no fim do artigo.
Espero que ajude 🙂
Cumprimentos,
Nuno Santos
Não estou conseguindo achar o código completo. Alguém pode disponibilizar o mesmo ?
Boa noite,
Neste post não tenho nenhuma secção com o código completo. Na altura em que escrevi ainda não tinha o hábito de colocar o código completo no fim do artigo 🙂
No entanto, basta utilizar o primeiro bloco de código (que contem os includes de bibliotecas, o setup e o loop) e depois as duas definições das funções de handling das rotas, que se encontram no fim do artigo.
Espero que ajude 🙂
Cumprimentos,
Nuno Santos
Thanks so much for the simple and elegant explanation. I will make sure to cite your post and mention your in the acknowledgements section of the paper.
Hi!
Thank you very much for the feedback and for mentioning the post in your paper 🙂
May I ask what does the paper cover?
Best regards,
Nuno Santos
Thanks so much for the simple and elegant explanation. I will make sure to cite your post and mention your in the acknowledgements section of the paper.
Hi!
Thank you very much for the feedback and for mentioning the post in your paper 🙂
May I ask what does the paper cover?
Best regards,
Nuno Santos
Thanks so much for a most informative and elegantly written explanation for the usage of query arguments. I will make sure to cite your post and show my gratitude for your help in the acknowledgement section of my paper.
Thanks so much for a most informative and elegantly written explanation for the usage of query arguments. I will make sure to cite your post and show my gratitude for your help in the acknowledgement section of my paper.
Hello
The arg parameter is passed as a string.
How can I convert this string value into an integer value?
Thank you
Nice tutorial, very easy to follow.
Is there a way to handle arguments without values? For example http://name.your.color?blue&green
If I do the equivalent of ‘if (server.arg(“Temperature”)== “”)’ to test which colors have been listed I think it will return an empty string, right? So ‘if(server.arg(“blue”)==””)’ would fail?
Hi. I land more and more on your pages very regularly when looking for help on ESP8266 usual tasks. Nice job !
Just a word about quotes: you seem to say that the issue is with the way they are copied from browser to Arduino IDE, but I really think the issue lies in the way you created the pages, because the issue is already in your html (see this screenshot : https://www.screencast.com/t/HzMUW70126 )
I would advise you to fix your pages once and for all instead of forcing each of your readers to fix them :-). Your site would be even more friendly…
Keep on the good work !
Yes, I confused of theat symbols. Could you show the right one? I am newby on esp and html
Now my watering ESP6288 can understand universal arguments. Setting the valves, setting the timers by web request :-). Thank you for the clear tutorial :-).