AJAX Request Body Empty (No jQuery) - javascript

I am trying to solve this problem without using jQuery so that I can have a better understanding of how things work.
I am sending an AJAX request to a node server with a JSON object. The server can receive the request and respond but the request body is always empty. I have tried setting the request header to 'application/json' but for some reason this changes the form submission to POST the parameters to the URL, rather than use the Javascript function. If anyone could tell me why that is happening as well it would be much appreciated.
Form
<form onsubmit="sendEmail(); return false;">
<input type="text" name="fromEmail">
<input type="text" name="subject">
<textarea name="message" rows="14"></textarea>
<input type="submit" value="SEND">
</form>
Email Function
function sendEmail() {
var emailContent = JSON.stringify(
{
email: $('input[name=fromEmail]').val(),
subject: $('input[name=subject]').val(),
message: $('textarea[name=message]').val()
}
);
var httpRequest;
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.open('POST','/message', true);
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
alert(httpRequest.responseText);
}
}
httpRequest.send(emailContent);
}
Node JS Routing
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// set body parser
app.use(bodyParser.json());
// Process email form
app.post('/message', function(req,res) {
console.log('Request received by email path.');
console.log(req.body);
res.send('{"success": true}')
console.log('Response sent.')
});

I think I understood your problem, what you need is to call the function sendEmail() without doing a postback. Well, for this you will nead a regular html button instead of a form submit. Forms are used to execute server requests to an specific url and generate another postback.
You have two options:
1) Do a client side call using a button and an ajax request (XMLHttpRequest):
<input type="text" name="fromEmail">
<input type="text" name="subject">
<textarea name="message" rows="14"></textarea>
<input type="submit" value="SEND">
<button type="button" onclick="sendEmail()">Send</button>
2) Use a form submit and call the service directly form the form. The parameters will be taken from the form and will be sent in the request:
<form action="/message" method="post">
<input type="text" name="fromEmail">
<input type="text" name="subject">
<textarea name="message" rows="14"></textarea>
<input type="submit" value="SEND">
</form>
Then in the server side you can access the data using the names you gave to the fields:
fromEmail = req["fromEmail"]

If you are trying to send json response, you need to set the content type of response as json.
res.setHeader('Content-Type', 'application/json');

You can try this:
httpRequest.open('POST','/message', true);
httpRequest.setRequestHeader("Content-Type","application/json");
httpRequest.send(emailContent);
Reference:
http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp

Related

Sending two post request with html form and AJAX at once

I´m trying to make two POST requests to different sites:
One from the action attribute form tag , and the otherone using AJAX (specifically XMLHttpRequest) on the onsubmit event.
Here is a snippet I made that IS WORKING on chrome browser (it sends first the ajax POST and then the form post) , but IT DOESN´T work in firefox (it only sends the POST action form).
Form action POST request
<form name="form_log" method="POST" action="Site1.php" onsubmit="return validate(this);">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="Submit" value="Enter">
</form>
AJAX POST request
function validate(){
if(document.form_log.username.value == ""){
alert('User name is empty');
return false;
}
if(document.form_log.password.value == ""){
alert('Password is empty');
return false;
}
else{
var user=document.getElementsByName('username')[0].value;
var pass=document.getElementsByName('password')[0].value;
var parameters=`username=${user}&password=${pass}&Submit=Enter`;
var url = "http://Site2.php";
var xhttp = new XMLHttpRequest();
xhttp.open('POST',url,true);
xhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhttp.onreadystatechange = ()=>{
if(xhttp.DONE && xhttp.status == 200){
console.log("SENT!");
}
}
xhttp.send(parameters);
}
}
Am I doing something wrong, and this behaviour is due to a Firefox restriction?
Thanks in advance !!
I tried this snippet on chrome and works OK! , but I can´t make to send both POST request on Firefox (it only sends the POST action request).

My JavaScript isn't working as intended, how can I correct and clean up this XHR POST request?

I have the following XmlHttpRequest:
var poc = new XMLHttpRequest();
poc.open("POST", URL);
poc.setRequestHeader("CUSTOM-HEADER", extract);
poc.send();
console.log("Request sent with header");
I'm wanting to submit POST body data alongside this XmlHttpRequest. Let's say the HTTP POST request is as follows:
POST /user/updateField/1554 HTTP/1.1
Host: localhost
Connection: close
Content-Length: 142
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytxuXi4RTyonGC5pD
------WebKitFormBoundarytxuXi4RTyonGC5pD
Content-Disposition: form-data; name="access"
winner
------WebKitFormBoundarytxuXi4RTyonGC5pD--
I can devise a HTTP Form to perform this POST request:
<html>
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://localhost:4442/user/updateField/1554" method="POST" enctype="multipart/form-data">
<input type="hidden" name="access" value="winner" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
So taking the above into account, I could devise the following XMLHttpRequest with the above Form data, as per below snippet:
function send() {
let form = document.forms['inputform'];
fetch(form.action, {method:'post', body: new FormData(form)});
}
send();
<form name="inputform" action="somewhere" method="post" enctype="multipart/form-data">
<input type="hidden" name="access" value="winner" />
</form>
<!-- for PoC -->
Look: chrome console > network and click <button onclick="send()">send</button>
However, this results in the fact that HTML is required for the XmlHttpRequest to be successful. I need this same functionality to be written purely in JavaScript but I'm struggling to achieve this.
I could try doing something along these lines, although I don't think the logic, or syntax is correct here:
function submitRequest() {
var poc = new XMLHttpRequest();
poc.open("POST", URL);
poc.setRequestHeader("CUSTOM-TOKEN", extract);
poc.document.body.innerHTML = '<html><body><script>history.pushState('', '', '/')</script><form id="dynForm" action="https://localhost:4442/user/updateField/1554" method="POST" enctype="multipart/form-data"><input type="hidden" name="access" value="winner" /><input type="submit" value="Submit request" /></form><script>document.forms[0].submit();</script></body></html>';
document.getElementById("dynForm").submit();
poc.send();
}
submitRequest();
Can someone please assist by writing the JavaScript in the context illustrated above? Your help will be greatly appreciated.
Thank you for your time.
Create a FormData object and add the parameter to it.
var poc = new XMLHttpRequest();
poc.open("POST", URL);
poc.setRequestHeader("CUSTOM-HEADER", extract);
var fd = new FormData();
fd.append('access', 'winner');
poc.send(fd);
console.log("Request sent with header");
Note that FormData is normally only needed when uploading files. For a single string parameter, you can use URL-encoded format.
poc.send('access=winner');

Javascript xmlhttp send api requests from forms

I have a server running locally which has an in built rest api. To login through this api, we need to send username, password and organization as parameters to url localhost:8090/ehr/api/v1/login via POST method and server returns an auth token as response. when I try to do this directly without user input from form through the following code:
<html>
<body>
<script type="text/javascript">
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.write(this.responseText);
console.log(this.responseText);
}
};
xhttp.open("POST", "http://localhost:8090/ehr/api/v1/login", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("username=admin&password=admin&organization=123456");
</script>
</body>
</html>
It works perfectly fine and auth token is returned as json, but if I try to do the same through user form input via following code:
<html>
<body>
<form method="POST">
<input type="text" name="username" id="username" placeholder="Username">
<input type="password" name="password" id="password" placeholder="Password">
<input type="text" name="organization" id="organization" placeholder="Organization">
<button id="submit" onclick="login()">Let me in!</button>
<br><br>
</form>
<script type="text/javascript">
function login() {
var user=document.getElementById("username").value;
var pass = document.getElementById("password").value;
var org = document.getElementById("organization").value;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.write(this.responseText);
console.log(this.responseText);
}
};
xhttp.open("POST", "http://localhost:8090/ehr/api/v1/login", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var param = "username="+user+"&password="+pass+"&organization="+org;
xhttp.send(param);
}
</script>
</body>
</html>
this code throws error
login.html:26 XHR failed loading: POST "http://localhost:8090/ehr/api/v1/login"
What is wrong with the second code and how to correct it?
send your params in this way
xhttp.send('username=user&password=pass&organization=org');
I figured it out myself, I just removed form tag from html and used simple input tags instead. This solved the problem maybe because forms on submission try to load a new page instead of staying on the same page, but the parameters were intended to get fetched from the original page. Which was not able to happen as new page got loaded every time submit button was clicked.

multipart/form-data possible to send with javascript?

I am sending a file over POST together with text "name" using this form:
<form enctype="multipart/form-data" action="https://site[DOT]net/upload" method="post">
<input id="name" type="text" />
<input id="data" type="file" />
<button type="submit" name="submit" />
</form>
I would like to do the exect same using javascript. In addition I dont want to be redirected. I want to stay on the html page and just show a popup "Upload done". How can I do this in javascript (no jquery)?
EDIT:
I tried this code but the POST is not working:
<script>
function uploader {
var formData = new FormData();
formData.append("name", "Smith");
formData.append("data", fileInputElement.files[0]);
var request = new XMLHttpRequest();
request.open("POST", "https://site[DOT]net/upload");
request.send(formData);
}
</script>
<form>
<input id="name" type="text" />
<input id="data" type="file" />
<button type="submit" name="submit" />
<button onclick="uploader()">Click</button>
</form>
In case any wants to do this with the new fetch instead of xhr this is the equivalent. Also see: How do I POST with multipart form data using fetch?
var form = document.getElementById('formid');
form.onsubmit = async (e) => {
e.preventDefault();
const form = e.currentTarget;
const url = form.action;
try {
const formData = new FormData(form);
const response = await fetch(url, {
method: 'POST',
body: formData
});
console.log(response);
} catch (error) {
console.error(error);
}
}
<form id="formid" enctype="multipart/form-data" action="#" method="post">
<input id="name" type="text" />
<input id="data" type="file" />
<button type="submit" name="submit">Submint</button>
</form>
Uploading the entire form with javascript, including the files, can be done by using the FormData API and XMLHttpRequest
var form = document.getElementById('myForm'); // give the form an ID
var xhr = new XMLHttpRequest(); // create XMLHttpRequest
var data = new FormData(form); // create formData object
xhr.onload = function() {
console.log(this.responseText); // whatever the server returns
}
xhr.open("post", form.action); // open connection
xhr.send(data); // send data
If you need to support IE10 and below, it gets increasingly complicated, and would in some cases require posting through iFrames etc.

Simple AJAX commenting system

I'm trying to make a simple AJAX commenting system. I'm not experienced with it. Here's my code:
function sendComment() {
var obj = { //make an object to send via ajax
values: [document.forms['commentform']['getpage'].value, document.forms['commentform']['commentname'].value, document.forms['commentform']['writingcomment']]
};
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xhr = new XMLHttpRequest();
} else { // code for IE6, IE5
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
xhr.open('POST', '/postcommentwritings', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(obj)); //stringify the object to send via ajax
}
<div class="comments-section">Comments</div> <a id="reader-delete-btn" class="menu-reader-viewer">…</a>
<div class="comments-container">
<div class="comments-container-child">
<form name="commentform" onsubmit="return validatecomm()" method="POST">
<input type="text" name="commentname" placeholder="Optional: give yourself a name">
<br>
<textarea name="writingcomment" id="writeComment" placeholder="comment.."></textarea>
<input type="hidden" name="getpage" value=<%=story.ID %>>
<input type="submit" onclick="sendComment()" value="submit">
</form>
</div>
</div>
and this is the server side node.js code for the route responsible for posting the comment and saving it to the database but it's too long and unnecessary so I'll just be putting the new code which screwed things up:
router.post('/postcommentwritings', function(req, res){
var commentsObj = {
post_ID : false,
name: "",
comment: false
}
var getObj= JSON.parse(obj);
for(x in getFoo){
commentsObj['post_ID'] = getObj[x][0];
commentsObj['name'] = getObj[x][1];
commentsObj['comment'] = getObj[x][2];
}
Then I continue with my normal code which works perfectly. But the problem is with either the ajax script on the HTML or this part of the code in the route. I genuinely don't know. The error only tells me "cannot look up view error". It's an ejs error so I suppose the problem might be with the front end part. Something else that might maybe help is that the route /postcommentwritings gets me a status of 500 in the node command prompt. It doesn't get connected to. So to those who're experienced with AJAX what is the problem and how do I fix it? Thank you all in advance.

Categories

Resources