Through spiffs, I am able to host a web server in which I have created a simple form which asks for input from a user. I am facing an issue I tried many solutions, and I saw many articles, but they were using html in their sketches. So basically, I need to get the data from whatever the user inputs on that html form and it should be disaplyed to a serial monitor . I am using a Arduino IDE. Here is my code.
#include "WiFi.h"
#include "SPIFFS.h"
#include "ESPAsyncWebServer.h"
const char* ssid = "ramesh";
const char* password = "rameshlike";
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_file.html", "text/html");
});
server.begin();
}
void loop(){}
here's my html code
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<script>
function message_popup() {
alert("Saved value to ESP SPIFFS");
setTimeout(function(){ document.location.reload(false); }, 500);
}
</script>
</head>
<body>
<form action="/get" target="hidden-form">
Enter string <input type="text" name="input_string">
<input type="submit" value="Submit" onclick="message_popup()">
</form><br>
<form action="/get" target="hidden-form">
Enter Integer <input type="number " name="input_int">
<input type="submit" value="Submit" onclick="message_popup()">
</form><br>
<form action="/get" target="hidden-form">
Enter Floating value <input type="number " name="input_float">
<input type="submit" value="Submit" onclick="message_popup()">
</form>
<iframe style="display:none" name="hidden-form"></iframe>
</body>
</html>
The html file is loading perfectly on the web server. but I am not able to find resources to get that data and print it on a serial monitor.
Simple HTML form:
<form action="POST" target="/someURL">
<input type="text" placeholder="someText" name="someText">
<button type="submit">Submit Form</button>
</form>
Simple endpoint:
// add a handler to an endpoint URL
// in here the second param must match with the form action
server.on("/someURL", HTTP_POST, [](AsyncWebServerRequest *request){
// get the param count.
int params = request->params();
// loop over the params.
for(int i=0;i<params;i++){
// get a reference to the param object at index.
AsyncWebParameter* p = request->getParam(i);
// print param values.
Serial.printf(
"name: %s\nvalue:%s\n",
p->name().c_str(),p->value().c_str()
);
}
// always respond to the client with something!
request->send(200,"text/plain","Got it!");
});
Note that inside your form you have to specify the action, either GET or POST or PUT or something, and the target url which in this case is "/someURL" and inside that form every input should have a name attribute and the submit button must have a type submit.
Oh and one more thing, use LittleFs instead of SPIFFS. It is working exactly the same as SPIFFS but much faster and reliable. Also SPIFFS is deprecated and LittleFs is built in too.
Here you can learn from everything that the EspAsyncWebserver provides: https://github.com/me-no-dev/ESPAsyncWebServer#body-data-handling
This code is untested, just an example to show you some idea.
Related
For the use of a google sheet stock management by several people, I use a sidebar for authentication (login). This running well, but i would like to allow different and simultaneous authentications (on different client computers)
In fact, my google scripts andZ html forms (integrated in userInterfaces) should be able to know and use the current agent, memorized by a sidebar field, as long as it is not closed.
I tried to use userProperties, scriptProperties, documentProperties,and cacheService but the connected agent is then memorized and common for all users instead of being specific to each workstation running the application. I have to work on the client side.
I know how to read and modify the DOM of the sidebar by the javascript code that i place there and also to recover this information within my google script. But here it is in fact a question of finding information from the instantiated sidebar.
My Apps Script:
function init_SideBar(e) { // init & show the sidebar
htmlSideBar = HtmlService.createHtmlOutputFromFile('htmlSideBar')
.setTitle('htmlSideBar')
.setWidth(300);
htmlSideBar.info="blabla"; // could it be a lead ?
SpreadsheetApp.getUi().showSidebar(htmlSideBar);
}
function gScriptFcGiveToSidebar() { // to send datas in an array to html page
let jSONforSheet= JSON.stringify(objForSheet);
return jSONforSheet;
}
function calledFromFormSubmit(sidebarForm) { // Receive datas from html sidebar
agentConnected=sidebarForm;
if(agentConnected=="Deconnecté"){
ss.toast("Deconnecté")
}else{
ss.toast("Bonjour "+agentConnected);
}
}
htmlSideBar.html:
<html>
<head>
<title>HTML DOM Objects</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
</head>
<body>
<label for="dowloading">dowloading</label>
<script>
function submitForm() { // envoi les données du form "sidebarForm" vers la fonction qui dans google script va les récupérer
// login & password verification (tablUser contains a column au login and a column of mp)
var elmts=document.getElementById("sidebarForm");
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
if (sidebarObj.tablUser[iUsers][0]==elmts.agentId.value){
if(sidebarObj.tablUser[iUsers][1]==elmts.mpId.value ){
document.getElementById('labelConnectId').innerHTML =elmts.agentId.value;
google.script.run.calledFromFormSubmit(elmts.agentId.value);
return;
}
}
}
alert ("password false, try again");
}
function deconnect(){
document.getElementById('labelConnectId').innerHTML ="Deconnecté";
document.getElementById('agentId').value ="Deconnecté";
google.script.run.calledFromFormSubmit("Deconnecté");
}
function jsFcGiveToForm(jSONforSheet){ //
$('#rangeResult').text(jSONforSheet); //$('#rangeResult').text(<nom de la variable qui va finalement délivrer au js, les données du google script>)
sidebarObj=JSON.parse(jSONforSheet);
document.write('<label id="labelConnectId" form="sidebarForm" > '+sidebarObj.agentConnected+'</label>');
document.write('<br><input type="button" value="Deconnect" onclick="deconnect();" />');
document.write('<form id="sidebarForm">');
document.write('<select name="agent" id="agentId">');
document.write('<option value="'+sidebarObj.agentConnected+'">'+sidebarObj.agentConnected+'</option>');
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
document.write('<option value="'+sidebarObj.tablUser[iUsers][0]+'">'+sidebarObj.tablUser[iUsers][0]+'</option>');
}
document.write('</select>');
document.write('<br /><input type="text" name="mp" id="mpId" value="password">');
document.write('<br /><input type="button" value="Submit" onclick="submitForm();" />');
document.write('<input type="button" value="Close" onclick="google.script.host.close()" />');
}
document.close(); // HYPER IMPORTANT !! libere le navigateur pour qu il continu a charger la page
google.script.run.withSuccessHandler(jsFcGiveToForm).gScriptFcGiveToSidebar();
</script>
</form>
</body>
</html>
Some leads ? :
Must i use scriptless
<?= blablabla?>
Using Meta tags :
var x = document.createElement("META");
x.setAttribute("name", "description");
x.setAttribute("content", "blablabla");
document.head.appendChild(x);
Using a property of htmlOutpu:
htmlSideBar.info="blabla";
Thanks a lot for your participation ! :)
I found a solution and described the sequences using the commented steps A1-4 and B1-12) which you just have to follow
Sidebar.gs:
function init_SideBar(e) { //A-1) init & show the sidebar.html
htmlSideBar = HtmlService.createHtmlOutputFromFile('htmlSideBar')
.setTitle('htmlSideBar')
.setWidth(300);// n'est plus modifiable fixé par google à 300 px
htmlSideBar.info="blabla";
HtmlService.SandboxMode=HtmlService.XFrameOptionsMode;
SpreadsheetApp.getUi().showSidebar(htmlSideBar);
}
function gScriptFcGiveToSidebar() { // A-3) to send google sheet datas (array or json...) to htmlSideBar.html page
let jSONforSheet= JSON.stringify(objForSheet);
ss.toast("json"+jSONforSheet);
return jSONforSheet;
}
function gScriptFromSidebarThenGiveToFormIn(sidebarAgent,provenanceFlag){
//Browser.msgBox("2 4 sidebarAgent="+sidebarAgent+" cache="+cacheService.get('sidebarAgent')+"init="+init);
if (provenanceFlag==false) { // B-7) Called by the de html htmlFormIn...withSuccessHandler(jsFcGiveToFormIn)
// Utilities.sleep(8000); // simulating an excess of a retention time of the cache
sidebarAgent=cacheService.get('sidebarAgent'); // B-8) Retieve the useful data in the cache
if (sidebarAgent==null) {return "echec";} // B-9) Abort in case the cache got lost (retention time exceeded)
cacheService.remove('sidebarAgent'); // B-10) Free the cache
return sidebarAgent; //B-11) give to formIn.html the data it expects
}else{ // B-2) provenanceFlag=true means that the call is from the htmlSideBar.html file buton.onclick , (sidebarAgent has the useful data)
if (cacheService.get('sidebarAgent')!=null) return false // B-3) cache not freed, abort proces for try again in a few time
cacheService.put('sidebarAgent',sidebarAgent,5); // B-4) Stock in cache the data for 5 secondes
initFormIn(sidebarAgent); //B5 open the user interface formIn.html that will have to take imediately the data in the cache, then free it
}
}
function calledFromFormSubmit(sidebarForm) { // Receive datas from html sidebar
agentConnected=sidebarForm;
//userProperties.setProperty('agentConnected', agentConnected);
if(agentConnected=="Deconnecté"){
ss.toast("Deconnecté")
}else{
ss.toast("Bonjour "+agentConnected);
}
//SpreadsheetApp.getActiveSheet().appendRow(["test",sidebarForm]);
}
htmlSideBar.html:
<!DOCTYPE html>
<html>
<head>
<style>
body { font-size:1em; }
p { color : red; }
</style>
<title>HTML DOM Objects</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
</head>
<body>
<label for="dowloading">dowloading</label>
<?= info?>
<script>
function callFormIn(){ google.script.run.gScriptFromSidebarThenGiveToFormIn(document.getElementById("labelConnectId").innerHTML,true);
}
function submitForm() { // My connect process
var elmts=document.getElementById("sidebarForm");
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
if (sidebarObj.tablUser[iUsers][0]==elmts.agentId.value){
if(sidebarObj.tablUser[iUsers][1]==elmts.mpId.value ){
document.getElementById('labelConnectId').innerHTML =elmts.agentId.value;
google.script.run.calledFromFormSubmit(elmts.agentId.value);
return;
}
}
}
alert ("mp faux");
}
function writeLabelAndTxtBox(name,id,value){
document.write('<br /><label for="'+name+'">'+name+': </label>');
document.write('<br /><input type="text" name="'+name+'" id="'+id+'" value="'+value+'">');
}
function writeLabel(name){
document.write('<br /><label for="'+name+'">'+name+': </label>');
}
function writeTxtBox(name,id,value){
document.write('<br /><input type="text" name="'+name+'" id="'+id+'" value="'+value+'">');
}
// -----------------------------------------------------------------------------------------------------------------
function clearAndClose(){
google.script.host.close();
}
function deconnect(){
document.getElementById('labelConnectId').innerHTML ="Deconnecté";
document.getElementById('agentId').value ="Deconnecté"; // facultatif ?
google.script.run.calledFromFormSubmit("Deconnecté");
}
function jsFcGiveToSidebar(jSONforSheet){ // A-4) I can Fill the sidebar.html page with json datas received from apps script about goole sheet
// End of the A1-4) states
sidebarObj=JSON.parse(jSONforSheet); // in particular sidebarObj.tablUser[] that contains the sheet columns of logins and passwords
/* sidebarObj.agentConnected was used to don't have to connect when open a new sidebar
(I dont speak aubout the google acount connection)
sidebarObj.keepConnectPropertie==false desactive this mode
i prefer now have to connect on each new sidebar instentiation.
the login is preserved while the sidebar is instantiated.
*/
document.write(new Date().toLocaleDateString());
if (sidebarObj.keepConnectPropertie==false){sidebarObj.agentConnected="Deconnecté"}
document.write('<label id="labelConnectId" form="sidebarForm" > '+sidebarObj.agentConnected+'</label>');
document.write('<br><input type="button" value="Deconnect" onclick="deconnect();" />');
document.write('<form id="sidebarForm">');
document.write('<select name="agent" id="agentId">');
document.write('<option value="'+sidebarObj.agentConnected+'">'+sidebarObj.agentConnected+'</option>');
for(let iUsers=0;iUsers<sidebarObj.tablUser.length;iUsers++){
document.write('<option value="'+sidebarObj.tablUser[iUsers][0]+'">'+sidebarObj.tablUser[iUsers][0]+'</option>');
}
document.write('</select>');
writeTxtBox('mp','mpId','password')
document.write('<br><input type="button" value="Submit" onclick="submitForm();" />');
document.write('<br><input type="button" value="FormIn" onclick="callFormIn();" />'); // B-1) run gScriptFromSidebarThenGiveToFormIn() with data parameter needed
document.write('<input type="button" value="Close" onclick="google.script.host.close()" />');
}
document.close();
google.script.run.withSuccessHandler(jsFcGiveToSidebar).gScriptFcGiveToSidebar(); // A-2) give to jsFcGiveToSidebar() the return of gScriptFcGiveToSidebar()
</script>
</form>
</body>
</html>
htmlFormIn.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<style type="text/css">
.myDiv {cursor:pointer;}
.divBlack{background-color:#000; color:#fff;}
</style>
<label for="dowloading">dowloading</label>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
// ---------------------------------------------- Functions for Javascript ------------------
function writeLabel(name){
document.write('<br /><label for="'+name+'">'+name+': </label>');
}
function writeTxtBox(name,id,value,prefix){
prefix=prefix||'<br />';
document.write(prefix+'<input type="text" name="'+name+'" id="'+id+'" value="'+value+'">');
}
// -------------------------------------------------Wrinting in Body -----
function addRow(){
cptLine++;
//alert(sidebarAgent); // alert(document.getElementById("idLblSidebarAgent").innerHTML);
//document.getElementById("tableForm").appendChild("tr");
let newLin = document.getElementById("tableForm").insertRow(-1); // ajoute un <tr> à la fin de la table
let newCell=newLin.insertCell(0); // ajoute un <td>
newCell.innerHTML = '<input type="text" name="" id=c"'+cptLine+'" value="v'+cptLine+'"> <input type="text" name="" id=d"'+cptLine+'" value="'+sidebarAgent+'">';
//alert("ajouté");
}
function jsFcGiveToFormIn(aagent){ // B-12) aagent receive the data value return from gScriptFromSidebarThenGiveToFormIn that have been called in A6 state
// B-13) the formIn.html can fill its fields :) - End of the B1-12) states
if (aagent=="echec"){ alert ("htmlFormIn 71 le cache service n'a pas memorisé assez longemps le transfert de donnée depuis la sidebar")}
sidebarAgent=aagent; // pour étendre la portée de cette info dans le script de cette page html
document.write('<label id="idLblSidebarAgent" for="info">'+sidebarAgent+'</label>')
writeTxtBox("Saisie","idSaisie","Entrez un code");
document.getElementById("idSaisie").addEventListener("click", addRow);
document.write('<form id="sidebarForm">');
document.write('<table id="tableForm"><tr id="r'+cptLine+'""><td>');writeTxtBox("Date","iddat","date"," ");writeTxtBox("Ref","idRef"+cptLine,""," ");
writeTxtBox("agent","idAgent",sidebarAgent," ");
document.write('</td></tr>')
document.write('</table>')
document.write('</form>');
}
document.close();
var cptLine=0;
var sidebarAgent;
google.script.run.withSuccessHandler(jsFcGiveToFormIn).gScriptFromSidebarThenGiveToFormIn("",false); // B-6) give to jsFcGiveToFormIn the return of gScriptFromSidebarThenGiveToFormIn("",provenanceFlag=false) with provenanceFlag=false that meaning the call is from formIn.html file.
</script>
</body>
</html>
I am trying to create a charge for Stripe using node.js. So I have followed Firebase method to see if I could get this working:
For clarity, I have left out the polymer elements imports. Assume all is well.
/charge.html:
<dom-module id="stripe-charge">
<template>
<script>
var firebaseStripe = new Firebase('https://blahblah.firebaseio-demo.com/');
firebaseStripe.set({
var stripe = require("stripe")("sk_test_blahblah");
var stripeToken = request.body.stripeToken;
var charge = stripe.charges.create({
amount: 1000, // amount in cents, again
currency: "gbp",
source: stripeToken,
description: "Example charge"
}, function(err, charge) {
if (err && err.type === 'StripeCardError') {
// The card has been declined
}
});
</script>
</template>
<script>
Polymer({
is: 'stripe-charge',
});
</script>
</dom-module>
index:
<section data-route="charge">
<stripe-charge></stripe-charge>
</section>
routing.html:
page('/charge', function () {
app.route = 'charge';
});
page({
hashbang: true
});
form:
<form is="iron-form" id="myForm" action="http://localhost:3000/#!/charge" method="post">
<input type="hidden" is="iron-input" id="amount" name="amount" bind-value="{{total}}">
<input type="hidden" id="stripeToken" name="stripeToken"/>
<input type="hidden" is="iron-input" id="stripeEmail" name="stripeEmail" bind-value="{{emailInput}}"/>
</form>
<paper-button class="fullBtn" id="customButton" on-click="stripe">
<iron-icon icon="icons:credit-card"></iron-icon>
Pay
</paper-button>
When I press the pay button, fill out card details etc, then hit the Strip pay button, I get the green but when it goes to the charge page, I get POST http://localhost:3000/ 404 (Not Found) Somehow it's not going to the page. Any ideas? I feel there will be more errors but for now, I want to get that page. Firebase issue?
Change your url be a true path, not a hash location:
<form is="iron-form" id="myForm" action="http://localhost:3000/charge" method="post">
You need to run a server that accepts the post and then makes a call to Stripe with your private key, you cannot run Stripe as a pure client-only process.
The first step in the browser calls stripe and packages up the supplied credit card information, but then you need to provide that token to your server. Otherwise anyone could submit charges on your behalf, including refunds!
I've tried to read similar postings. Couldn't get a clue on my code about why mine is still going to the php page displaying messages and not showing on the original html page.
Here is the code snippet.
In javascript
$(document).ready(function(){
$("#myForm").submit(function(){
var url = $(this).attr("action");
var str=$(this).serialize();
$.post(url,str,function(msg){$('msg_div').show();$('msg_div').html(msg);});
return false;
});
});
in html
<form name="myForm" action="abc.php" method="post" enctype="multipart/form-data">
...
<input type="submit" name="Submit" id="Submit" value="Submit" onClick="return validateForm()"/>
in PHP
if (mail($to, $subject, $msg, $headers)) echo "<p>hank you for your query.</p>";
else {
echo "<p>Error: email failed."; die('Error!');
}
What has gone wrong with this code? Thank you in advance.
Have a good day and All the best,
Allison
I see that you tried to stop the behaviour of submitted forms (with return false, which seems fine), I did this once too but don't now in which project that was, so I don't have any sample right now.
Maybe this helps (but didn't test it yet):
$("#myForm").submit(function(e){
e.preventDefault();
var url = $(this).attr("action");
var str=$(this).serialize();
$.post(url,str,function(msg){$('msg_div').show();$('msg_div').html(msg);});
return false;
});
The e.preventDefault(); should stop the submit process. How does your validateForm() look like?
I have:
<form method="POST" name="f">
<input type="file" name="FileUpload" id="FileUpload" />
</form>
I'm sent the file using ajax,using the uplaod.file method:
document.getElementById('FileUpload').onchange = function() {
file = this.files[0];
ajax = new XMLHttpRequest;
ajax.file = file;
//etc..
ajax.open('post','Default.aspx', true);
ajax.setRequestHeader('foo','baa');
ajax.send(file);
}
Request.Forms["FileUplaod"] // don't works
How I get the value (the file) sent by ajax in my asp.net application?
I tried sent by http headers(is not pratice good,I know) but there problem with long length.
Thanks in advance.
try this form attribute :
form action="some/action" method="POST" enctype="multipart/form-data"
UPDATE
So it turns out internet exploder's stranglehold on "security" to "make up" for being so bad at security was causing my problems. I should have checked that out first haha. Thanks everyone for the input, it has given me ideas on how to optimize my application :D
I am writing a web app (in ASP.NET 3.5) that integrates with a platform app. The platform app takes the user's credentials and puts them into an "empty" HTML page that consists of a form with hidden items containing said credentials and POSTS to the webapp (default.aspx):
<HTML>
<HEAD>
<SCRIPT LANGUAGE=JSCRIPT>
function OnLoad(){
try {
document.form1.submit();
}
catch(e){
}
}
</SCRIPT>
</HEAD>
<BODY OnLoad="OnLoad()">
<FORM ACTION="http://localhost:51816/gs_ontheweb/default.aspx" METHOD=POST NAME=form1 TARGET="_NEW">
<INPUT TYPE="HIDDEN" NAME="ClientID" VALUE="123456">
<INPUT TYPE="HIDDEN" NAME="Password" VALUE="2830088828">
<INPUT TYPE="HIDDEN" NAME="PracType" VALUE="051">
<INPUT TYPE="HIDDEN" NAME="Encrypt" VALUE="12345620081111">
</FORM>
</BODY>
</HTML>
When my default.aspx page gets loaded up, it calls the following function:
Dim ClientID As String = Request.Form("ClientID")
Dim PassWord As String = Request.Form("Password")
Dim PracType As String = Request.Form("PracType")
Each one of them result in empty strings. Any ideas on why this is happening? Thanks in advance.
EDIT: Is there something I need to configure in my web.config file to make this work properly? Request.Params("<param name>") does not work.
Your issue is the "Target" property on the Form. Why is this here?
(I also took the liberty of cleaning your HTML up a little)
<html>
<head>
<title>Test JS Post</title>
<script type="text/javascript" language="javascript">
<!--
function OnLoad(){
try
{
alert("Posting...");
document.form1.submit();
}
catch(e)
{
alert("ERROR!");
alert(e);
}
}
//-->
</script>
</head>
<body onload="OnLoad()">
<form action="http://localhost:49684/Default.aspx" method="post" name="form1">
<input type="hidden" name="ClientID" value="123456" />
<input type="hidden" name="Password" value="2830088828" />
<input type="hidden" name="PracType" value="051" />
<input type="hidden" name="Encrypt" value="12345620081111" />
<h1>This is in the form. Submit me here:</h1><input type="submit" value="foo" />
</form>
</body>
</html>
In the code behind of Default.aspx:
Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
For Each value As String In Request.Form.Keys
Debug.WriteLine(String.Format("{0} = ""{1}""", value, Request.Form.Item(value)))
Next
End Sub
That HTML is just on the user's harddrive? Maybe the browser security won't let that POST because it's deemed to be a risk.
As a test -- take that exact HTML file and put it on your webserver and then browse to it. If it works, might be the browser refusing to send the data. You could check with Fiddler (for IE) or Firebug in FireFox.
Why not use System.Net.WebClient?
Some sample code (sorry, it's C#. Looks like your looking for VB. I can't translate quickly.)
System.Net.WebClient wc = new System.Net.WebClient();
byte[] b;
byte[] res;
string formdata = "text=test text&password=secret&checkbox=on&textarea=a longer text sentence&submit=submit";
// encode the form data string into a byte array
b = System.Text.Encoding.ASCII.GetBytes(formdata);
// set the content type for a form
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
// POST and get data
res = wc.UploadData("http://localhost:51816/gs_ontheweb/default.aspx", b);
//convert the return page from byte[] to ascii
string s = System.Text.Encoding.ASCII.GetString(res);