So I'm developing a website where a section of the website will be provide means to send comments to us on how to improve it. This section will ask for the user's name, email address, and have a text box. I want the user to be able to click send and have that message as well as their name and email address to be delivered to a designated email address.
That way the admins of the website can look over the website and attempt to make the content more relative to what the users demand. I'm using NodeJS but what I'm confused about is how to actually implement that. I've never done anything like with communication to the backend so I'm very confused on how to start.
Initially, I thought I could make a php script with HTML to do that function, but knowing that NodeJS is a server side scripting language, I know there should be some way to incorporate that in my web application. I googled but I'm a beginner with NodeJS so I was not fully ably to comprehend. If someone could assist me with this problem, it would be highly appreciated.
Thank you so much!
When you have to create a page with a webform, you have to create GET and POST request.
On your GET request you have to display a valid HTML page.
To do that you have to choose a template engines, I use handlebar but you are free to choose your own (jade, ejs, ...).
Exemple:
//index.js
var express = require('express');
var app = express();
var expressHbs = require('express3-handlebars');
app.engine('hbs', expressHbs({extname:'hbs'}));
app.set('view engine', 'hbs');
app.get('/pages/contact', function(req, res){
res.render('contact');
});
//contact.hbs
// this form send a post request to /pages/contact
<form action='/pages/contact' method='post'>
<input type='text' name='username' id='username'/>
<input type='text' name='mail' id='mail'/>
<input type='text' name='message' id='message'/>
</form>
If you want to add more security controls on your form take a look at helmet.
On your POST request, you have to do an action, here it's to save the form (or send information via email).
You need to validate your input data
You need to sanitize your input data
You need to proccess your data to mongodb, nodemailer or mandrill
Take a look at express-validator.
Exemple:
//index.js
var expressValidator = require('express-validator');
app.post('/pages/contact', function(req, res) {
// VALIDATION
// checkBody only checks req.body
req.checkBody('username', 'Invalid username').notEmpty().isAlpha();
req.checkBody('mail', 'Invalid email').isEmail();
req.checkBody('message', 'Invalid message').notEmpty();
// SANITIZE
req.sanitize('message').escape().trim();
var errors = req.validationErrors();
if (errors) {
res.send('There have been validation errors: ' + util.inspect(errors), 400);
return;
}
// Proccess your data here via mandrill, nodemailer or mongoose.
});
Another popular solution is to use caolan/forms.
PS: Send an email is not a simple task, take a look at mailchimp, mandrill, mailjet, mailgun ...
You can send all the data in POST to your node.js server. That way you can get these informations back in the body of your request. I am using Express.js.
HTML :
<form action='/sendMessage' method='POST'>
<input type='text' name='username' id='username'/>
<input type='text' name='mail' id='mail'/>
<input type='text' name='message' id='message'/>
</form>
Node.js :
app.post('/sendMessage', function(req, res){
console.log(req.body.message) //your message
console.log(req.body.username) //your username
console.log(req.body.mail) //your mail
//insert your code to send mail here
});
In order to send mails, I used nodemailer module which is easy to use (https://github.com/andris9/Nodemailer).
Were you at all trying to save the data people filled out? If so, going off of the solution above, in addition to console.log, you could write the data to one of these tools:
Using the file system and write to a text file: https://nodejs.org/api/fs.html#fs_fs_writefile_filename_data_options_callback
Or.
MongoDB:
https://github.com/mafintosh/mongojs
There are a lot of free cloud databases for mongo, and provide plenty of examples to get started.
Related
I'm trying to make a post call via an html page. On 2nd application, i'm trying to access a cookie named cookie_test (can be set manually or via code in browser).
Under Application tab(Storage --> cookies), i'm able to see the cookie, but somehow i'm getting undefined in console log when trying to access it from 2nd application (refer 2nd code).
browser cookie screenshot
Application One (test.html is the only file in it & i'm trying to make a post call)
<form action="http://localhost:3000/page-two" method="POST">
<input type="submit" value="Go to P2">
</form>
Application Two (NodeJS/Express:
index.js)
var express = require('express');
var router = express.Router();
router.post('/', function (req, res, next) {
console.log("COOKIE-TEST::::::", req.cookies.cookie_test)
res.render("page_two", { cookie_data: req.cookies.cookie_test });
});
module.exports = router;
Note: Within node application, cookies are accessible & works as expected. Issues seems to happen during redirection.
I was able to solve the issue by setting the cookie parameters as secure(true) & sameSite(none). Make sure to use latest version of express for sameSite property. This setting allowed my 2nd application to access it's cookies, irrespective of getting redirected from any source (in my case Application one).
A couple of things to check.
First, your nodejs app needs the cookie-parser middleware if it is to receive any cookies from users' browsers. It looks like this.
var cookieParser = require('cookie-parser')
...
var express = require('express')
express.use(cookieParser())
...
You didn't mention how you set the cookie from your post route. You would do that like this with a call to res.cookie():
router.post('/', function (req, res, next) {
console.log("COOKIE-TEST::::::", req.cookies.cookie_test)
const testCookieVal = req.cookies.cookie_test || 'some default value'
res.cookie('cookie_test', testCookieVal)
res.render("page_two", { cookie_data: someCookieVal })
});
It's not clear how you set the cookie you're trying to retrieve in your post route. You should understand that your Application One html file is served from the file:// origin, and Application Two is served from the https://localhost:3000 origin. Browsers never send cookies associated with web pages served from one origin in requests to other origins.
I have a simple html form on a webapp, in which the user can input information
<form>
Field 1: <input class="pod" type="text" name="Field1" value="Test1"><br>
Field 2: <input class="Start-Date" type="text" name="start-date"
value="2019-03-29"><br>
</form>
Once the user inputs this information I simply need to grab it, which I can do on the HTML file through some jquery:
<script>
$(document).ready(function() {
var test = $(".pod").val();
});
</script>
So this works on the HTML file. I can't however get this to work on the .gs file and I am lost on how to accomplish that. I need the user input to run SQL and return some data afterward. All documentation I found was rather confusing and didn't me help much, so I hope that somebody can help me here.
Alternatively: How can you use a variable defined on the HTML file on the GS file? For instance, what if I grabbed the information through the example code on the html file, is there a way to call this variable (var test) on the GS file?
Thank you a ton,
Sascha
Grab your user input from frontend
Pass that to backend using run
Execute your SQL in backend using the user inputs received.
Return the result from backend
Receive response from backend in frontend using withsuccesshandlerfunction
Reference : How to send data from HTML form to Google Spreadsheet using JavaScript?
I'm trying to learn ESP32. My self-given project has the following steps:
set ESP32 as a softAP - DONE
access ESP32 via WiFi - DONE
serve an HTML authentication form (index1.html)(that's inside the flash memory of the ESP32) asking for a nearby Wireless Network's SSID and Password - DONE
type the above mentioned credentials, click on a Log-In button and connect the ESP32 to that Wireless Network
switch to a different web page (index2.html)(that's inside the flash memory of the ESP32)
Hardware:
Board: ESP32 DEVKIT1
Core Installation version: 1.0.1-git this one
IDE name: Arduino IDE
Flash Frequency: 80Mhz
PSRAM enabled: no
Upload Speed: 115200
Computer OS: Linux Mint 19.1 Mate
Since I am a complete noob I've done a lot research but found nothing that I knew how to apply with my project, that's why I am writing this post.
Since I don't understand how to properly post code here (I've read this) (code /code did not work, typing > at the beginning of each line did not work), because it will get interpreted instead of just COPY-PASTE, I made some gists. I hope they work.
index.html
https://gist.github.com/GeorgeFlorian/d52ed6fb10e4beaf8f64ef5edef2a78b
login.css
https://gist.github.com/GeorgeFlorian/8d976c512e5ddbc1a5506cc35a0326a2
Arduino IDE Sketch
https://gist.github.com/GeorgeFlorian/d0b6ff502675ef7599aa74d8d8aa706f
Now I would like to be able to type in SSID and Password into their respective input, click on "Sign in" button, store those in a read-only file inside the Flash Memory of the ESP32, connect the ESP32 to the respective Wireless Network and serve another web-page from inside the Flash Memory.
I didn't mention using JavaScript or PhP because I have no idea which one should be use or if they even work this way.
Also, instead of a read-only file can there may be a small database stocking only a few Wireless Networks ?
Thank you ! Sorry for the long post.
I've never messed with the ESP32 or web services running on microcontrollers, but I mostly write web services and applications for a living.
You could use JavaScript to read the form values and submit an HTTP request to a separate endpoint to store the username and password values, but HTML already supports forms.
The input tags you have now work with forms. All you have to do is add a form element around your inputs that specifies how to encode and transfer the form values, and what endpoint to send them to. The browser will take care of the rest when you click on the submit button:
<body>
<div class="login-box">
<form method="post" action="/login">
<div class = "box-head">
<div class = "logo"><img url="logo.png"></div>
<div class = "network-title"><h1>Network Login</h1></div>
</div>
<div class ="textbox">
<input type="text" placeholder="Network Name" name="networkName" value="">
</div>
<div class="textbox">
<input type="password" placeholder="Password" name="networkPassword" value="">
</div>
<input class="button" type="submit" value="Sign in">
<input class="button" type="reset" value="Restart">
</form>
</div>
</body>
This would send an HTTP POST request to the /login endpoint with a body containing the form values encoded as application/x-www-form-urlencoded.
You don't need PHP to handle the request (and you don't have a PHP runtime to begin with). PHP executes logic on the HTTP server. In this case, the ESP32 is your HTTP server, and your logic is captured by the AsyncWebServer object inside your sketch.
AsyncWebServerRequest can read form values for you, so all you have to do is implement the correct handler on your server:
server.on("/login", HTTP_POST, [](AsyncWebServerRequest *request) {
if (!request->hasParam("networkName", true) || !request->hasParam("networkPassword", true)) {
request->send(400, "Missing fields");
return;
}
const char *networkName = request->getParam("networkName")->value().c_str();
const char *networkPassword = request->getParam("networkPassword")->value().c_str();
// Do stuff with networkName and networkPassword
// ...
// Redirect to new page
request->redirect("/whatever");
});
I am new to the node js. I have and html form which is having file input like -
<form action="importlist_action" method="post" enctype="multipart/form-data">
Select File:
<input type="file" name="file" id="file" tabindex="1" />
</form>
Now, I have redirected this post request to the following method of controller.
exports.doImport = function(req, res) {
console.log('Post values: ' + JSON.stringify(req.body));
console.log("File path : " + req.body.file);
}
The result I am getting here is -
Post values: {}
File path : undefined
I want the path of the file which is selected on the form above in the controller. can some one please correct me what I am doing wrong here?
Any help will be really appreciated.
If you're using Express 3.x and the bodyParser() middleware, then you should look under req.files for files.
If you're using Express 4.x, then you have to use a separate module to read a multipart request. Examples of such modules are: busboy(/connect-busboy/multer/reformed) and formidable.
As #adeneo mentioned, not all browsers provide the actual file path, but most will at least supply a filename. Both Busboy and Formidable make the filename available to you.
You have to be careful that node.js does not upload files in a folder by default like PHP would.
What you are probably looking for is a middleware to do this for you:
http://www.senchalabs.org/connect/bodyParser.html
I finished Ryan Bates #348 video for creating a JSON API using the rails-api gem. I have it working as in the example. However, in his example he has the page that calls the API in the same project. My goal is to separate out the client app from the API app.
I created a second rails app that simply includes the page that does a JSON request for the API data and a post when submitting the form. I have the client app running on localhost:3000 and the API running on localhost:4000.
Below is the client side code. It successfully submits a new deal record, but the
GET doesnt load the list of deals. When looking in the logs it appears it is requesting it as HTML. When the page was apart of the same API project, the same code was making the call as JSON in the logs.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
$(function() {
function addDeal(deal) {
$('#deals').append('<li>' + deal.name + '</ul>');
}
$('#new_deal').submit(function(e) {
$.post('http://localhost:4000/deals', $(this).serialize(), addDeal);
this.reset();
e.preventDefault();
});
$.getJSON('http://localhost:4000/deals', function(deals) {
$.each(deals, function() { addDeal(this); });
});
});
</script>
<div id="container">
<h1>My Deals</h1>
<form id="new_deal">
<input type="text" name="deal[name]" id="deal_name">
<input type="submit" value="Add">
</form>
<ul id="deals"></ul>
</div>
Because of Cross Origin Policy you have following options:
Use jsonp (don't do this since you have your server :) check below )
Manage Cross Origin Resource Sharing on server, recently I wrote answer here how to achieve this
You could use rails ActiveResource::Base to conect to your api, but it may be slow, and you would repeating yourself unless there is some presentation logic you need on backend. BTW, check Nibbler gem it may be somewhat better... it really depends what you need to do in backend.
Anyhow. I would avoid approach 1, its kinda overhead especially if you want to POST, PUT or DELETE, and you can allows use option 2 if you have pure javascript app running as UI. But even if you are building JS agnostic app you always need a bit of backend processing so option 3 is probably something you'd prefer.