form submit vs separate XMLHttpRequest - javascript

I'm working with Node.js and have express as my main framework.
I have a login webpage with the following code.
<script>
function sendResponse(){
var data = new FormData();
var login = document.getElementById("login").value;
var password = document.getElementById("password").value;
data.append('login', login);
data.append('password', password);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://myURL/login', true);
xhr.onload = function () {
// do something to response
var result = JSON.parse(this.responseText);
if(result["result"] == "fail"){
alert("No Account Found. Please Register First.");
window.location.replace("http://myURL/register");
}
else{
window.location.replace("http://myURL/mainpage");
}
};
xhr.send(data);
}
</script>
<h1>Login Portal</h1>
<hr />
<form method="post">
<table>
<tr>
<td><label>Username or Email:</label></td>
<td><input id="login" type="text" name="login" /></td>
</tr>
<tr>
<td><label>Password:</label></td>
<td><input id="password" type="password" name="password" /></td>
</tr>
</table>
<button type="button" onclick="sendResponse()">Login</button>
</form>
Node.js can't send two responses for one request.
The html is not sent by a normal FORM-SUBMIT request but have a separate javascript function that creates a new httprequest instance and gathers info from the form and send it to the server, get the response back and do further actions from there (to register or the mainpage).
What my friend whats to do is make this a normal FORM-SUBMIT type with the action property targeted to the login url, and since I can only send one response, I would send a redirect and take control of the route-handling. But then since the client won't have other member data like before he would send another request through a separate route to get the logged-in member's data such as the session and the member's key.
When I look at many famous websites, the html code does implement what my friend described, and he wants to make the website through the standard procedures. He think my way of processing requests through an onclick trigger is a workaround. I get it, and I'm not the familiar with web developing, I'm in charge of the server. But doesn't this make the workload x2? I mean, if the client side can deal with post actions once it gets the data, isn't that not a workaround but a normal way of handling requests?

Node.js can't send two responses for one request
I don't think any web server can do this, unless you're using a duplex connection, like a websocket.
He think my way of processing requests through an onclick trigger is a workaround.
Either that or the submit event of the form. It's very versatile and is supported by pretty much any browser out rhere.

Related

Ajax : append form data to json file without php

I've been trying for hours to get this thing working.
I'm trying to append the text of Title and the text of Content to a .json file. I've seen a lot of similar problems on here but with php and I'm not allowed to use it (Rule of the teacher).
I tried Fetch API but I found out that it only handles get requests from json files. Yet I only found ajax functions on here where they use $ in front of them.
I just don't know how to include the location of the json file without using php. name file = posts.json.
Example inside json:
Picture json
This is my code JS:
let form = document.getElementById('frm');
form.addEventListener('submit', PostBlog)
function PostBlog(){
let title = document.getElementById("txtTitle");
let content = document.getElementById("txtContent");
let data = {title1: title.value}
//let url = new URL("http://localhost:8080/admin.html");
//let parms = new URLSearchParams({title1: title.value, content1: content.value});
fetch("http://localhost:8080/admin.html",
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data),
}
).then(receive).then(response => response.text()).then(Succeed).catch(problem)
}
function receive(response) {
if(!(response.ok)){
throw new Error("Didn't Receive " + response.status);
}
return response;
}
function problem(error){
alert("Not Found " + error);
}
function Succeed(data){
alert("Found " + data);
}
HTML important part:
<form id="frm">
<div class="form-group">
<label for="txtTitle">Title</label>
<input type="text" class="form-control" id="txtTitle">
</div>
<div class="form-group">
<label for="txtContent">Content</label>
<textarea class="form-control" id="txtContent" rows="3"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="reset" class="btn btn-primary">Reset</button>
</div>
</form>
And finally a picture of the site
Picture of the site
Ajax is a term meaning "Making an HTTP request from JavaScript, running in the browser, without leaving the page".
You can't use it to directly write to data on the server, because browsers aren't allowed to simply write to servers. If that was possible, then the Google homepage would be vandalised 30 times per second.
You need a server-side process to take the HTTP request and write the data to the file (although a database is usually a better bet as that will take care of problems like simultaneous writes). If you don't want to use PHP then you can use any other server-side programming language the server supports. If you don't want to use any of those then you can change your server to one that supports the language you want to use.
I tried Fetch API but I found out that it only handles get requests from json files.
The Fetch API can be used to make more-or-less any kind of request with any kind of payload and any kind of response.
Yet I only found ajax functions on here where they use $ in front of them.
Browsers have two APIs for making Ajax requests. XMLHttpRequest and Fetch. (Fetch is newer).
There is numerous third-party libraries that wrap XMLHttpRequest and/or Fetch to provide alternative APIs. $ is the variable to which jQuery is commonly assigned. Its main Ajax helper function can be found in the ajax property.
The use of a third-party library won't solve the issue that browsers can't write to servers.

Include two https requests in Node js via the same html button

I have an HTML button that sends a POST request and would like to do some kind of verification before making the request here.
The verification involves a GET request, where I make sure that a certain table contains a certain value or not. After that, if the condition is valid I make the POST request else I use the value I fetched from the GET request.
Even though this sounds basic I'm not sure how to do this in Nodejs.
Here is how code is organized now,
Her is the HTML button:
<form action="/generate_survey" method="POST" id="gen_survey">
<button type="submit" class="btn btn-primary my-3">Get Survey Link</button>
</form>
And I have a router.js that includes all the routes:
route.get('/generate_survey', controller.test)
then here in the controller.js, I have the db and other call functions.
So here is the test function where I want to make the request
exports.test = (req, res)=>{
.....
}
Should I put the GET request results in a variable and then depending on that I make the POST request?
If so I'd like to see an example of how to something similar in Nodejs
Thanks
In Angular we can do this way. so hope same applies to Nodejs as well. adding form method just for ref. you can check the actual one.
form onsubmit="do_something()"
do_something(): boolean{
// do get operation here
return true; // submit the form
return false; // don't submit the form
}

Passing Javascript variables into PHP

I am working on a login system where you hash the password on the client side, before sending it to the server. I have got as far as grabbing the password and hashing it, and now I just need to insert it into the database and/or compare for a login.
<form action="javascript:;" onsubmit="return changeFormLogin()">
<p>Email</p>
<input id="username" type="email" name="username" placeholder="Enter Email" required>
<p>Password</p>
<input id="getPass" type="password" name="password" placeholder="••••••" required>
<input type="submit" name="login" value="Sign In">
<p id="demo"></p>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.9.0/sha256.min.js" ></script>
<script>
function changeFormLogin() {
var pass = document.getElementById('getPass').value;
var username = document.getElementById('username').value;
var getSalt = 123566;
var hashpass = sha256(pass+pass);
console.log(hashpass);
var tmp = validateLogin(hashpass);
if(tmp ==1){
//Welcome the user back, and load new form
}
else{
//Tell them to try again, notify them.
}
document.getElementById("demo").innerHTML = hashpass; //Used for testing
return true;
}
For simplicity I always use a FormData object when sending data
var fd = new FormData();
fd.append("Name", [VALUE]);
Then send that object in an XmlHttpRequest
Also, I don't really do security so I wouldn't know, but should the hashing be done server side?
Why not shift the entire encryption logic to the server side and insert into the database ? This way you just change action to your server page and POST it.
But if if you want to keep it this way, then you can do a ajax call in your JavaScript function.
Refer : https://www.w3schools.com/js/js_ajax_http_send.asp
Note: Although no one can reverse hash this thing, but still passwords will be visible from developer tools and brute force algorithm can be applied to get the password, so doing this thing in server is recommended
Edit :
Form submit with AJAX passing form data to PHP without page refresh
You could:
Send the information in a form using a POST or GET request (will result in a page refresh).
Use AJAX/XMLHttpRequest (without a page refresh).
Use a cookie.
Since you are trying to make a login system then I would recommend using a POST request (so it doesn't show the submitted info in the url bar) and a PHP session to check if the user has logged in yet (here's an example).
Not only that but if you want to keep your users login information private you shouldn't be using javascript for the authentication, search for tutorials on how to hash a password the right way, you'll find lots of related material on stackoverflow and information security.
PHP by default only supports bcrypt and argon but they are still better than SHA256 as SHA/HMAC is faster to computer and therefore faster to crack.

How to respond to login entries in a node js server

I have a website with a login form (username and password) and want to receive these inputs in a node js server file, where I will later use them as an object for a database query etc.
I want to know the best way of sending and receiving/dealing with this information. At the moment the form uses a "get" method, and the node js server file uses query string to parse the inputs into an object. I can do this and obtain the parameters; below is a code sample:
HTML:
<form id = "login" method="get" action="https://localhost:8443/index.html">
<input type="text" name="username" placeholder="Username" /><br/>
<input type="password" name="password" placeholder="Password"/><br/>
<input type="submit" value="log in" class="button"/><br />
</form>
Node JS example:
var QS = require('querystring');
var params = QS.parse(require('url').parse(request.url).query);
The only issue here is using the "get" method, which makes the entered fields (including password) visible in the URL. Is this a suitable approach in general?
I have also looked at using "post" as the method but could not find a way of parsing the query from the body of the request.
One approach that may be useful but I am unfamiliar with is using AJAX requests and responses through my script.js file.
Can anyone offer any helpful solutions?
Thanks!

Write into database before redirecting

There's a button, when it is clicked(html onclick) it redirects to another page. In javascript there's a function, that writes some new values into a database table when this button is clicked. My problem is: redirecting takes place before the data is written into the database, so on the new page i still have the old values. Is there an easy way to invert these steps(redirecting, writing into database)? Thanks for your advise
just move the redirection into the callback of an ajax call, say you have
Save data
<script type="text/javascript">
$(document).ready(function() {
$("#savedata").click(function() {
$.post('/savemydata/', { mydata: 'data' }, function(data) {
window.location.href = '/newpage/'
});
return false;
});
});
</script>
if the button actually submits the form, then you might probably want to hide the button instead and then just trigger it after your post simply by adding:
$("#buttonID").trigger('click');
Use ajax to write the data, then in the callback of the ajax throw in the redirect. This will ensure that the redirect does not happen until the information is written to the database. It would help to see some of your code to make a better answer. Also, this would most likely be best done with jQuery if you are new to ajax.
Move the code that redirects to a new page into the callback for your ajax save request.
Something like this:
$.post('/savemydata/', { my: 'data' }, function(data) {
//the Ajax post has been completed successfully, so now we redirect
window.location.href = '/newpage/'
});
That depends on how you are writing to the database. But the usual and recommended way to transport data to your server when loading a new page is the use of URL parameters. If you use something like
<form action="/next.php" method="POST">
<input type="hidden" name="data" value="values" />
<button type="submit" value="Next Page" />
</form>
or
Next Page
// also simply usable with
window.location = "/next.php?data=values";
you can be sure that
the data reaches the server,
can be processed (written to the database) before
the requested page is returned.
You could also make use of cookies. Just write your data values into document.cookie, and they will be transported to the server with the same request that asks for the new page.

Categories