What happens when we submit a form in HTML if action attribute is empty or contains a url

Hello guys, sorry to disturb you all; I have built a small server using node and express js. Now I have built a small login form. What I want to do is send the form to the server; their I will need to perform some validation etc. But how do I send the form to the server ? Also, say my form web page is on localhost:3030 and my server on localhost:8080, how do I do communicate please
35 Replies
glutonium
glutonium5d ago
if action attribute is empty or contains a url
the action attr , i can recall correctly is used when u want to send the form data. since u r using nodejs u dont need to worry about it (i think).
how do I send the form to the server
through api request , and with POST method since u r posting data
Also, say my form web page is on localhost:3030 and my server on localhost:8080, how do I do communicate please
through API .
fetch("https://localhost:8080", obj)
.then()
.catch()
fetch("https://localhost:8080", obj)
.then()
.catch()
now u might face cors issue. for that u would need the cors middleware in server
Jochem
Jochem5d ago
sorry, but that's way overcomplicating it depending on the way the server is set up at least if the server is set up to just receive a POST form submission, then you can just put the full URL in the action attribute including the port number
Faker
FakerOP5d ago
I didn't yet set up a route for POST information but I will do it, what I will do: Create a specific route related to users; on this route, we will be able to: GET users POST users (register new user) PUT (update user) DELETE (delete user)
Jochem
Jochem5d ago
you can do that all either with HTML form submissions, or by intercepting the submit events and using fetch. Using the form submissions is more reliable, accessible, and generally better practice, unless you really need the page to not reload on submit
Faker
FakerOP5d ago
hmmm normally the website should be a single page web app, so I think it shouldn't reload... what I was thinking of doing at first: Set up a special route for every HTTP method on users Then, in the action attribute let it be empty since we can't have several html pages meaning http post request is for actual webpage itself We then extract the information from the request body something like that
Jochem
Jochem5d ago
hmm, if you want to do that then yes, what glutonium aid. You'd register a submit handler on the form, and you can then use fetch to send the request to an API endpoint and handle the result in javascript
Faker
FakerOP5d ago
I was looking on stackoverflow... I found something simple, like this:
const express = require('express');
const path = require('path');

const app = express();
const port = 3000;

app.use(express.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname,'public')));

app.post('/api', (req, res) => {
console.log(req);
})

app.use('/',(req,res,next) => {
res.sendFile(path.join(__dirname,'public','index.html'));
});


app.listen(port, () => console.log(`App is listening on port ${port}!`))
const express = require('express');
const path = require('path');

const app = express();
const port = 3000;

app.use(express.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname,'public')));

app.post('/api', (req, res) => {
console.log(req);
})

app.use('/',(req,res,next) => {
res.sendFile(path.join(__dirname,'public','index.html'));
});


app.listen(port, () => console.log(`App is listening on port ${port}!`))
Will that work for a single page web app ?
Jochem
Jochem5d ago
yeah, it should, I think
Faker
FakerOP5d ago
Ok ok, when would we use the fetch API ? like for form submission I mean
Jochem
Jochem5d ago
with your htmL
<form id="coolform">
<input />
</form>
<form id="coolform">
<input />
</form>
you could use js to submit the data
document.querySelector('#coolform').addEventListener('submit', (event) => {
event.preventDefault();//prevent the regular submission from going through

const formData = new FormData(event.target);
//process the data here, validate, check, enrich, or just repackage as required by your backend
fetch('https://localhost:port/api', { options_here })
.then((res) => {
//process results
});
});
document.querySelector('#coolform').addEventListener('submit', (event) => {
event.preventDefault();//prevent the regular submission from going through

const formData = new FormData(event.target);
//process the data here, validate, check, enrich, or just repackage as required by your backend
fetch('https://localhost:port/api', { options_here })
.then((res) => {
//process results
});
});
Faker
FakerOP5d ago
yeah I see but the thing is we have 2 methods to submit the form ? One using client side javascript then the other one using our back-end javascript, express in this case?
Jochem
Jochem5d ago
you have a submit on the frontend and a place to receive it on the backend, yes express doesn't submit anything, it's just the endpoint you send your data to
Faker
FakerOP5d ago
yeah I see, so I either choose to use the fetch or using our back-end script (will do both just to see how it works :c) but is there a prefered method here ?
Jochem
Jochem5d ago
No, the backend script is always required, the frontend can either use the built in form submission or fetch
Faker
FakerOP5d ago
yeah I need to experiment, let me use the submission and the back-end script first just to try but I think I have understood what you are trying to convey: The thing is we need both a front-end for form submission and a back-end script to handle the submission. Now for the front-end, we can either rely on the default submission or use our own logic. Using our own logic is better ? Because we can customize validation in our own way? Like password length etc ? From what I read, if we use the default submission, the page reloads (I need to experiment that, did not understand yet what it means.... like we are redirected? or we need to refresh the page to send the data to a specific endpoint ?) Concerning the back-end, we always need it to parse the data sent
Jochem
Jochem5d ago
you're redirected, yes. The browser does a request to the form's action attribute and then goes from there. The backend generally either renders something based on the form, or redirects back to somewhere else I wouldn't say one is better than the other. It's a good idea in general to have the form submission as a fallback, if you can. It's usually best to stick with default and built-in functionality, but form submissions are usually handled with fetch nowadays because of the flexibility
Faker
FakerOP5d ago
hmmm what do you mean by the back-end may redirects back from somewhere else please.... if our attribute is left empty, we would need to manually refresh our web-page?
Jochem
Jochem5d ago
do remember though that you can never, ever, ever trust anything that's coming from the frontend. If you validate in the frontend, you validate for the convenience of your end user. The backend has to rerun any validation and checks
Faker
FakerOP5d ago
like using in-built HTML validation, such as for emails and required attribute fields ?
Jochem
Jochem5d ago
no, if the attribute is left empty I think it defaults to submitting the current page's own URL? also not to be trusted
Faker
FakerOP5d ago
ah I see, I will just experiment and reverred back but even here we would have a page reload ?
Jochem
Jochem5d ago
the only code you can trust is backend code, frontend code can be modified or circumvented by a malicious user
Faker
FakerOP5d ago
yepp I see hmmm small question, when might we want to use the default submission? I think I'm only thinking about "form submission" that's why in my head, I only wanted to go with the customized submission
Jochem
Jochem5d ago
hmm, the answer used to be "everything", from sign in to filtering a form to a lot of other stuff. The advantage is that it works even if your javascript fails. Nowadays, it's used a lot less though. It's easier to upload files with a regular submission, I think?
Faker
FakerOP5d ago
hmmm what I'm confused about is say we have a simple HTML form with some styling, using css file but we don't have anyJS files. If we click on the buttom submit, there is still some JS which happen under the hood that submit the form, right ? Now if we use the default submission, each time we click the button, won't the form be always submitted? unless we prevent its default but its no longer regular submission no ? I'm confuse about what we mean by regular submission and customised submission I think :c can you just clarify please
Jochem
Jochem5d ago
no, no JS. It's part of the browser the browser just takes the contents of the form, adds it to a post or get request, and sends the request to the server. That has nothing to do with JS. You can intercept that request using JS, but the basic form submission doesn't use javascript at all
Faker
FakerOP5d ago
hmm but then there is no validation taking place in the front-end ?
Jochem
Jochem5d ago
you can use HTML attributes to do some validation but yeah, it can theoretically submit without validation which, again, isn't an issue other than for ease of use for the end user, because frontend validation should NEVER be trusted
Faker
FakerOP5d ago
yeah I see
glutonium
glutonium5d ago
if validation matters a lot then it should always be done in the server even if u r doing it in the FE cause bare in mind. client side code CAN be viewed and manipulated by the user
Faker
FakerOP5d ago
yep I will just experiment a bit and come back
document.querySelector('#login').addEventListener('submit', (event) => {
event.preventDefault(); // Prevent default form submission

const formData = new FormData(event.target);

fetch('http://127.0.0.1:5500/Server/public/HTML/form.html', {
method: 'POST', // Specify the HTTP method
body: formData, // Send the FormData object
})
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json(); // Parse JSON response if applicable
})
.then((data) => {
console.log('Success:', data); // Handle success
})
.catch((error) => {
console.error('Error:', error); // Handle errors
});
});
document.querySelector('#login').addEventListener('submit', (event) => {
event.preventDefault(); // Prevent default form submission

const formData = new FormData(event.target);

fetch('http://127.0.0.1:5500/Server/public/HTML/form.html', {
method: 'POST', // Specify the HTTP method
body: formData, // Send the FormData object
})
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json(); // Parse JSON response if applicable
})
.then((data) => {
console.log('Success:', data); // Handle success
})
.catch((error) => {
console.error('Error:', error); // Handle errors
});
});
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import {router} from '../routes/root.js'
import cors from 'cors';



const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const port = 8080;
const app = express();

//CORS - Cross Origin Resource sharing
const allowedOrigins = ['http://127.0.0.1:5500', 'http://localhost:8080'];
const corsOptions = {
origin: allowedOrigins,
optionsSuccessStatus: 200,
};

app.use(cors(corsOptions));

// Serve static file
app.use('/M00967932', express.static(path.join(__dirname, '../public')));

// Handle form submission
app.use(express.urlencoded({extended : false}));


//JSON parser
app.use(express.json());


app.use('/M00967932', router);

app.listen(port, () => {
console.log(`Server started on port ${port}`);
})
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import {router} from '../routes/root.js'
import cors from 'cors';



const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const port = 8080;
const app = express();

//CORS - Cross Origin Resource sharing
const allowedOrigins = ['http://127.0.0.1:5500', 'http://localhost:8080'];
const corsOptions = {
origin: allowedOrigins,
optionsSuccessStatus: 200,
};

app.use(cors(corsOptions));

// Serve static file
app.use('/M00967932', express.static(path.join(__dirname, '../public')));

// Handle form submission
app.use(express.urlencoded({extended : false}));


//JSON parser
app.use(express.json());


app.use('/M00967932', router);

app.listen(port, () => {
console.log(`Server started on port ${port}`);
})
I want to send data from my front-end server to my back-end server. Both uses different ports. I configure the cors settings etc, but I get error 405 in my front-end even though I do have the method post The thing is the url of the form.html differs in the front-end and back-end is it because of that ?
glutonium
glutonium5d ago
form.html means a file it is not a route it is a file name also Server/public/HTML/form.html is a very weird route if this route is handling log in the u should call it something like /api/v1/login also u r doign app.use('/M00967932', router); which if i am not wrong, sets /M00967932 as the base route. any other route u set using the router will have to be preceeded by this which does not exist here http://127.0.0.1:5500/Server/public/HTML/form.html
Faker
FakerOP5d ago
yeah no, the thing is I'm launching my server using express on say localhost:8080/M00967932 Now I use the extension for local server on vscode to launch my webpage, form.html. This webpage has another route and base url.... both url of my server differs hmm I think I got the error, it was related with the url and my id :c hello, sorry to disturb you, just notice something, at first, I thought we were uing the "submit" button to submit the form but the event isn't on the button but on the form; this is what we mean by "general" form submission vs a customized one? Like for the customized one, we wouldn't use the submit event ? Everything need to be done from scratch ?
Jochem
Jochem5d ago
generally for the customized one, you'd hook into the submit event and cancel the default action
Faker
FakerOP5d ago
ah ok, yep I see, ty !!
Want results from more Discord servers?
Add your server