Send data POST Protocole with arduino to web page Javascript

Hi,
I try to send data to website with POST method wtih my Aruino to activate a Javascript function (Function sb(val)), which corresponds to a click on a button on the web page.

I found a way to retrieve the information from the page with the "GET" function.

However I can’t send the requette POST to activate this script, I can connect to the site but sending data does not work.

  if (client.connect(server_LIE, 1000)) 
  {
    client.println("GET / HTTP/1.1");
    //client.println("Host: 10.105.158.254");
    client.println("Connection: close");
    client.println();
    String answer=getResponse();
    Serial.println(answer);
  }  
  String data =String("val=") + 1;

  if (client.connect(server_LIE, 1000)) 
  {
    Serial.println("Send data to web site");
      // Make a HTTP request:
    client.println("POST / HTTP/1.1");
    client.println("Host: 10.105.154.258");
    client.println("Accept: */*");
    client.println("Content-Type: text/html");
    client.print("Content-Length :");
    client.println(data.length());
    client.println(data);
    client.println("Connection: close");
    client.println();
    delay(100);
  }

Any idea why it doesn’t work? Thanks for your help.

That's just not how things work. What happens is

  1. A user agent -- usually a browser, but here an Arduino -- makes a request to a web server. This request is usually a GET, but could be a POST, DELETE, etc
  2. The web server may respond with HTML
  3. The user agent will parse this HTML, which in this case contains at least one <form> and some <script>, which are converted into the corresponding things in the DOM and the function in JavaScript
  4. The user agent will trigger the function due to the user interaction with the <button>

You can't trigger JavaScript in a page if you don't have a JavaScript engine, for a page you did not receive and parse to build a DOM.

But based on what the sb function actually does, you might be able to do the equivalent without any JavaScript at all.

Look at the HTML and find the first (likely only) <form> -- first because the JavaScript said form[0]. Check for two attributes

  • method: if it's missing, it defaults to get, but it might be post
  • action: if it's missing, it's the current page's path, but could be something else starting with /

Possibly it has method="post" and no action, in which case you were close. But val is the variable name in the function in JavaScript and has no relation to what the web server expects. The form element -- between the form[0]. and .value is answer, so try sending

POST / HTTP/1.1
Host: 10.105.154.258
Content-Type: application/x-www-form-urlencoded
Content-Length: 8

answer=1

Note the blank line between the headers and the body, which you did not have. And strictly speaking, you don't need a line break after the body with println -- you say how many bytes to expect -- but it probably won't hurt.

The value of answer need to be encoded. And if it's a GET instead, the values go in the URL as query parameters.

Thanks you kenb4 for your answer.
Indeed in the HTML code it's method="post" and action="/".
Sans titre

I updated my Arduino code and I have no return from the web server I tried a ping but to www.google.com it does not work.

String data = "answer=1";
  if (client.connect(server_LIE, 1000)) 
  {
      // Make a HTTP request:
    client.println("POST / HTTP/1.1");
    Serial.println("POST / HTTP/1.1");
    client.println("Host: 10.105.158.254");
    Serial.println("Host: 10.105.158.254");
    client.println("Content-Type: application/x-www-form-urlencoded");
    Serial.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    Serial.print("Content-Length: ");
    client.println(data.length());
    Serial.println(data.length());
    client.println();
    Serial.println();
    client.println(data);
    Serial.println(data);
    client.println("Connection:close");
    Serial.println("Connection:close");
    client.println();
    Serial.println();
  }
  delay(100);
  String answer=getResponse();
  Serial.println(answer);

Here’s what I got:

this is part of the HTTP header fields and should be sent BEFORE the empty line
"data" is the last you want send
don't add println at the end - this will transmit two more bytes, and as you have told the server the length of data it makes no sense to send more.

but I guess your main problem is the content of data. What's in?

I updated the code like that :

String data = "answer=1";
  if (client.connect(server_LIE, 1000)) 
  {
    client.println("POST / HTTP/1.1");
    client.println("Host: 10.105.158.254");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(data.length());
    client.println("Connection: close");
    client.println();
    client.print(data);
  }

The data is "answer" that I want to change to 1 in the HTML code.

IP: 10.105.158.254 is a firewall disclaimer page with a button that accepts the conditions. The purpose of arduino code is to simulate the click of a button to access the internet and send an email from an SMTP server.

Have you tried to send the other hidden fields also? Exactly with the values the Arduino got - not the values from what you see in a browser.

This will be difficult to get working. What many people do on Arduino is "manually perform HTTP" by printing the headers and such to do one-off requests and grab the response. But the way this type of firewall works generally is another layer on top of that; essentially "manually perform like a browser"

In addition to answer, the form has two other hidden fields; you'll need to send those also, and the value that is an URL will have to be encoded. The response you receive may contain a cookie, designated with a Set-Cookie header in the response. You'll need to parse and store the cookie, and send it for any request that match its parameters.

The response will also likely have a redirect, which may contain some other unique identifying code. That may mean parsing the HTML. The response for the firewall or the original may contain other JavaScript, and that code might actually do something that is not as easy to replicate without actually executing -- or being simulated as -- JavaScript.

But first, you should be getting some kind of actual HTTP response to the POST, not -1. Try posting your whole sketch here, simplified and with any secrets redacted. Also include the responses as code too, not as a screenshot.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.