Submitting a form through Javascript via POST method - javascript

index.js
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#compose').addEventListener('click', compose_email);
document.querySelector('#compose-form').onsubmit = send_email;
// By default, load the inbox
load_mailbox('inbox');
});
function compose_email() {
// Show compose view and hide other views
document.querySelector('#compose-view').style.display = 'block';
// Clear out composition fields
document.querySelector('#compose-recipients').value = '';
document.querySelector('#compose-subject').value = '';
document.querySelector('#compose-body').value = '';
}
function send_email()
{
const recipients = document.querySelector('#compose-recipients').value;
const subject = document.querySelector('#compose-subject').value;
const body = document.querySelector('#compose-body').value;
//console.log(recipients)
fetch('/emails', {
method: 'POST',
body: JSON.stringify({
recipients: recipients,
subject: subject,
body: body,
})
})
.then(response => response.json())
.then(result => {
// Print result
console.log(result);
});
}
inbox.html
<div id="compose-view">
<h3>New Email</h3>
<form id="compose-form">
<div class="form-group">
From: <input disabled class="form-control" value="{{ request.user.email }}">
</div>
<div class="form-group">
To: <input id="compose-recipients" class="form-control">
</div>
<div class="form-group">
<input class="form-control" id="compose-subject" placeholder="Subject">
</div>
<textarea class="form-control" id="compose-body" placeholder="Body"></textarea>
<input type="submit" class="btn btn-primary"/>
</form>
</div>
Submitting a form through Javascript via POST method but I am getting an output of GET /? HTTP/1.1" 200 1667 in terminal..
It should be 201 via POST
When I am writing the fetch function in Console.It is working fine
After submitting the form it is just returning back to the inbox page.

Since you are doing a "fetch" in your code, you should prevent the default form submission on the "submit" button click (This this the default behaviour). To achieve this you can receive the "event" as a parameter in the "send_email" function and then do a "event.preventDefault()".
function send_email(event) {
// Your code
...
// Prevent the default form submission
event.preventDefault();
}
More details # https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onsubmit

Related

Sending data by html form (POST method)

I have a question regarding POST method. I'm trying to record the data from form into txt file. But the string is empty (in txt file I have only "The request: ")
HTML:
<form
action=""
method="POST"
id="form"
class="section-contact-me-form"
>
<fieldset>
<div class="section-contact-me-input">
<label class="section-contact-me-input__label" for="name">Name*</label>
<input
type="text"
name="name"
class="section-contact-me-input__input _req"
id="name"
>
</div>
<div class="section-contact-me-input">
<label class="section-contact-me-input__label" for="email">E-mail*</label>
<input
type="text"
name="email"
id="email"
class="section-contact-me-input__input _req _email"
>
</div>
<div class="section-contact-me-input">
<label class="section-contact-me-input__label" for="phone">Phone</label>
<input
type="text"
name="phone"
id="phone"
class="section-contact-me-input__input phone"
>
</div>
<div class="section-contact-me-textarea">
<label class="section-contact-me-textarea__label" for="message">Your message*</label>
<textarea
rows="10"
cols="45"
name="message"
id="message"
class="section-contact-me-textarea__textarea _req"
></textarea>
</div>
</fieldset>
<div id="submit" class="submit-button">
<button class="submit-button_active">Send data</button>
</div>
</form>
JS:
form.addEventListener("submit", formSend);
async function formSend() {
const formData = {
name: document.querySelector("#name").value,
email: document.querySelector("#email").value,
phone: document.querySelector("#phone").value,
message: document.querySelector("#message").value
};
const formDatatoSend = JSON.stringify(formData)
sendData("http://localhost:3000/101_susov_newDesign/contactme.php", formDatatoSend)
.then(() => {
form.reset();
})
.catch((err) => console.log(err))
};
const sendData = async (url, data) => {
const response = await fetch (url, {
method: "POST",
body: data
})
if (!response.ok) {
throw new Error (`URL with error ${url}, status ${response}`)
};
return await response;
};
PHP:
<?php
$value = $_POST['value'];
$f = fopen('file.txt', 'a+');
fwrite($f, "The request: ".$value."\n");
fclose($f);
?>
So, the server works properly: there is the access to php code and txt file refreshes every time I use form button, but the content sended from form is empty. As I told before in txt file I have only "The request: "
Where is the eror in my code? Thanks in advance and have a good day!
You do not have a field called value so $_POST['value'] doesn't return anything. You can get the value of each field by adding it's name attribute as the array key:
$value = $_POST['phone'] would return 'The request: PHONE_NUMBER' into your TXT file.
$value = json_encode($_POST) would return the whole post into your TXT file
This should work:
$value = json_encode($_POST);

File Upload With Vanilla Javascript (Form Data Object always empty)

I have been trying to upload an image to the server for a few days now. But server does not receive any image because form data object is always empty. I then tried to use a library called dropzone for image upload and it worked. But I dont want to use any library. Can somebody please help me understand why form data object is always empty when I send it? I would really appreciate it cuz it will also help me in future. Thank you.
Html Code
<form class="editProfileForm" encType="multipart/form-data">
<div class="form-group">
<div class="row">
<div class="col-12 mt-3">
<div class="text-left">
<label for="certificateImg">CertificateImage</label>
</div>
<input id="certificateImg" type="file" />
</div>
</div>
<div class="row">
<div class="col-sm-12 text-center mt-3 mb-5">
<button class="saveBtn btn btn-primary btn-brand-lg" type="button">Save</button>
</div>
</div>
</div>
</form>
JS Code
const editProfileForm = document.querySelector('.editProfileForm');
const saveBtn = document.querySelector('.saveBtn');
saveBtn.addEventListener('click', () => {
let img = document.getElementById('certificateImg').files[0];
let formData = new FormData();
formData.append('img', img);
console.log(formData);
const doctorUpdateGeneral = async () => {
try {
const response = await axios.put(
'API here',
{
certificate: formData,
},
{
headers: {
Authorization: token,
},
}
);
console.log(response);
window.location.reload();
console.log(pmdc);
} catch (err) {
console.log(err);
}
};
doctorUpdateGeneral();
});
Change the encType attribute to enctype in the form element tag

Close form without reloading page when sending post request to backend API

This is probably a simple one, but I have a React front end and Express back end, and I'm sending data to my API through a form on the front end. I have two buttons, one Submit and one Close. The Close button has a click event handler that closes the overlay without leaving the page. I would like my Submit button to work the same using the onSubmit handler. However, even though my post requests goes through successfully, it never closes the overlay despite using the same function.
I can make the app work by using a res.redirect on my back end to the home page, but I'd ideally like to not have the page reload. Additionally, when I have my back end send any kind of data back using res.send() or res.json(), it loads the JSON data in my browser instead of processing it in my front end (e.g. showing all posts in my Posts.js component).
Relevant code:
Post route
router.post('/', (req, res) => {
Post.create(req.body)
.then(newPost => {
console.log("Success!")
res.status(201).json(newPost);
//res.redirect('http://localhost:3000');
})
.catch(err => {
console.log(err);
res.send(err);
})
})
Form and Close overlay function
handleClose(e) {
this.props.closeForm();
e.preventDefault();
}
render() {
const postForm =
<div className="form-popup" id="newPost">
<form action="http://localhost:5000/api/posts" method="post" className="form-container">
<h1>New Blog Post</h1>
<div className="formArea formtitle">
<label htmlFor="title"><b>Title</b></label>
<input type="text" placeholder="Blog Post Title" name="title" required />
</div>
<div className="formArea formlocation">
<label htmlFor="location"><b>Location</b></label>
<input type="text" placeholder="Location" name="location" required />
</div>
<div className="formArea postcontent">
<textarea placeholder="Your post here" name="bodyText" required />
</div>
<div className="formArea formsubmit">
<button type="submit" className="btn" onSubmit={this.handleClose} >Post</button>
<button type="submit" className="btn cancel" onClick={this.handleClose}>Close</button>
</div>
</form>
</div>
Two options
Recommended: Send the request by JavaScript using an Ajax call
Hacky solution: Insert an iframe tag in your page and have the form have it as a target
XHR
var xhr = new XMLHttpRequest();
xhr.open("POST", '/server', true);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() { // Call a function when the state changes.
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
// Request finished. Do processing here.
}
}
xhr.send("foo=bar&lorem=ipsum");
iframe
<iframe name="formTarget" style="display:none;"></iframe>
<form action="http://localhost:5000/api/posts" method="post" target="formTarget">
<!--Your inputs and other form contents-->
</form>
Your issue has nothing to do with Node.js. Read about controlled components and axios.
To do it the react way, change your code to the following:
import React from 'react';
import axios from 'axios';
class YourComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
title: '',
location: '',
bodyText: ''
};
handleOnInputChange = (event)=> {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmitForm = ()=> {
const { title, location, bodyText } = this.state;
axios.post('http://localhost:5000/api/posts', {
userName: name,
userLocation: location,
text: bodyText
})
.then(response=> {
//Do something with the response
console.log(response)
})
.catch(error=>{
//Do something with the error
console.log(error)
})
}
}
render(){
<div className="form-popup" id="newPost">
<form className="form-container">
<h1>New Blog Post</h1>
<div className="formArea formtitle">
<label htmlFor="title"><b>Title</b></label>
<input type="text" placeholder="Blog Post Title" name="title" required value={this.state.title} onChange={event => this.handleOnInputChange(event)} />
</div>
<div className="formArea formlocation">
<label htmlFor="location"><b>Location</b></label>
<input type="text" placeholder="Location" name="location" required value={this.state.location} onChange={event => this.handleOnInputChange(event} />
</div>
<div className="formArea postcontent">
<textarea placeholder="Your post here" name="bodyText" required onChange={event => this.handleOnInputChange(event}>{this.state.bodyText}</textarea>
</div>
<div className="formArea formsubmit">
<button type="button" className="btn" onSubmit={this.handleSubmitForm} >Post</button>
<button type="button" className="btn cancel" onClick={this.handleClose}>Close</button>
</div>
</form>
</div>
}
}
export default YourComponent

Pass an image through AJAX [duplicate]

This question already has answers here:
How can I upload files asynchronously with jQuery?
(34 answers)
Closed 8 years ago.
Basically I want to pass a image file with ajax on submitting a form and retrieve the image and send it by email as an attachment file:
Here's the form :
<form role="form" action="" name="devis" id="devis" method="post" enctype="multipart/form-data" class="form-horizontal">
<fieldset>
<div class="form-group">
<label class="control-label col-md-4" for="societe">Company</label>
<div class="col-md-8">
<input type="text" class="form-control input-md col-md-8" name="societe" value="" maxlength="" id="societe">
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4" for="message"><span class="required">* </span>Message</label>
<div class="col-md-8">
<textarea rows="5" name="message" class="form-control input-md col-md-8" maxlength="" required="" style="resize:none;" id="message"></textarea>
</div>
</div>
<div class="form-group" id="input_file">
<label class="control-label col-md-4" for="image_input_field">Logo</label>
<div class="col-md-8">
<div class="input-group uploaddiv">
<span class="input-group-btn">
<span class="btn btn-default btn-file">
Parcourir <input type="file" id="image_input_field" name="file">
</span>
</span>
<input type="text" class="form-control" readonly="">
</div>
</div>
</div>
<div class="form-group">
<div class="form-actions col-md-9 col-md-offset-3 text-right">
<input type="submit" value="Envoyer" name="" class="btn btn-primary" id="submit">
<input type="reset" value="Annuler" name="" class="btn btn-default" id="reset">
</div>
</div>
</fieldset>
</form>
I can't seem to find what's the error in my code ! Here's the AJAX call :
jQuery(document).on("click", "#submit", function(e) {
e.preventDefault();
var fileInput = document.getElementById('image_input_field');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file);
// console.log(file);
var societe = $("input#societe").val();
var message = $("textarea#message").val();
jQuery.ajax({
url: "ajax.php",
type: "post",
data: {
'file': file,
'module' : 'ajax_data_form',
'societe': societe,
'message': message
},
cache: false,
success: function(reponse) {
if(reponse) {
alert(reponse);
// console.log(reponse);
// jQuery('#devis').trigger("reset");
} else {
alert('Erreur');
}
}
});
});
And here's the ajax.php:
<?php
if( isset($_POST['module']) && $_POST['module'] == "ajax_data_form" )
{
var_dump($_FILES);
}
$.ajax({
type: "POST",
url: pathname,
data: new FormData($('#devis')[0]),
processData: false,
contentType: false,
success: function (data) {
$("#divider").html(data);
}
});
and get the file data normally in $_FILES[];. Because FormData is automatically handles the multipart header in an ajax request.
can you try it
<script type="text/javascript">
$(document).ready(function() {
$("#submit").click(function() {
var fileInput = document.getElementById('image_input_field');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file);
// console.log(file);
var societe = $("input#societe").val();
var message = $("textarea#message").val();
$.ajax({
url: "ajax.php",
type: "POST",
data: "file="+file,
cache: false,
success: function(reponse) {
if(reponse) {
alert(reponse);
// console.log(reponse);
// $('#devis').trigger("reset");
} else {
alert('Erreur');
}
}
});
}); });
</script>
In ajax.php
just write
echo 'something';
As you may know already, it is not possible to process file uploads via ajax calls, it will be possible once HTML5 FILE I/O Api is ready and implemented by major browsers.
You can use jQuery iframe post form plugin to post data in iframe so user experience will be similar to ajax call (partial update of page).
Here is the link:
https://github.com/dogzworld/iframe-post-form
Description: "This jQuery ajax upload plugin creates a hidden iframe and sets the form's target attribute to post to that iframe. When the form is submitted, it is posted (including the file uploads) to the hidden iframe. Finally, the plugin collects the server's response from the iframe."
As mentioned you can send response from the server and display updates on your webpage accordingly.
There has to be a demo page but it is not working as of now.
You can also use it for file uploads.
Calling Example:
jQuery('#frmId').iframePostForm({
json : true,
post : function () {
//return true or false
return true;
},
complete : function (response) {
//complete event
console.log(response);
}
});
Using a Jquery Plugin Called Jquery Form plugin Link
I would suggest to simply submit the form using jquery and what ever data you want you can keep them in hidden fields.
$("#devis").ajaxSubmit(options);
return false;
The you can easily get the file in the php page like this
$ImageTempname = $_FILES['ImageFile']['tmp_name'];
$ImageFilename = $_FILES['ImageFile']['name'];
$ImageType = $_FILES['ImageFile']['type'];
and so on.....

Implemented reCaptcha... Still getting spam

I just implemented a reCaptcha on a WP Site contact form.
It works like this:
Submission is cancelled using $form.submit(function(e) { e.preventDefault(); return false; }
reCaptcha is dynamically inserted before the form.
if reCaptcha's AJAX response is successful, perform HTLMFormElement.submit, using $form[0].submit();
HTML
<div id="ny_cf-3" class="footer-ny widget widget_ny_cf"><h2 class="widgettitle">Contact Us</h2>
<!-- contact form widget -->
<p class="response"></p>
<form method="post" enctype="multipart/form-data" class="ny-footer-contact-form" action="http://wpstage.leadscon.com/leadsconny/" data-submit="return fm_submit_onclick(1)" id="fm-form-1" name="fm-form-1">
<div class="form-group" id="fm-item-text-53546749dea0d">
<input type="text" name="text-53546749dea0d" id="text-53546749dea0d" style="width:px;" placeholder="Your name" class="form-control">
</div>
<div class="form-group" id="fm-item-text-5354674e4b90b">
<input type="text" name="text-5354674e4b90b" id="text-5354674e4b90b" style="width:px;" placeholder="Email address" class="form-control">
</div>
<div class="form-group" id="fm-item-textarea-5354675009293">
<textarea name="textarea-5354675009293" id="textarea-5354675009293" style="width:px;height:100px;" placeholder="Your message" class="form-control"></textarea>
</div>
<input type="email" class="teddybear" style="display:none">
<button type="submit" id="fm_form_submit" name="fm_form_submit" class="btn btn-primary btn-block submit">Submit</button>
<input type="hidden" name="fm_nonce" id="fm_nonce" value="1165f15ac2">
<input type="hidden" name="fm_id" id="fm_id" value="1">
<input type="hidden" name="fm_uniq_id" id="fm_uniq_id" value="fm-536b89c742833">
<input type="hidden" name="fm_parent_post_id" id="fm_parent_post_id" value="4">
</form>
<!-- end cf widget -->
</div>
JavaScript code:
var getRecaptcha = function($form, $frmResponseField) {
$form.fadeOut();
// Add the reCaptcha
// ========================================================================
var $recaptchaForm = $('<form class="recaptcha_form" style="display:none;"><p><strong>Spam verification (sorry):</strong></p><p class="response"></p><button class="btn btn-success btn-sm" type="submit">Submit</button></form>');
var recaptcha_el = $('<div id="recaptcha_el"></div>').insertAfter($recaptchaForm.find('.response')).get(0);
$recaptchaForm.insertBefore($form).slideDown();
leadsCon.reCaptchaHTML().appendTo($(recaptcha_el));
Recaptcha.create('6LdUZPASAAAAAGZI_z-qQ7988o0nGouHHtIsh4yX', recaptcha_el, {
theme : 'custom',
custom_theme_widget: 'recaptcha_widget',
callback: Recaptcha.focus_response_field
});
// Bind submit action to check it
$recaptchaForm.submit(function(e) {
e.preventDefault();
var challenge = Recaptcha.get_challenge();
var response = Recaptcha.get_response();
var $btn = $recaptchaForm.find('button[type="submit"]')
var btnVal = $btn.html();
var $responseField = $recaptchaForm.find('.response');
var data = {
action: 'verify_recaptcha',
challenge: challenge,
response: response
};
$btn.html("<i class='dashicons dashicons-clock'></i>");
$responseField.text('');
$.post(ajax_object.ajax_url, data, function(response) {
if ( response.success == true ) {
$responseField.removeClass('text-danger').addClass('text-success').html('<i class="icon-ok"></i> You got it. One second...');
// We're ok.. send.
Recaptcha.destroy();
$recaptchaForm.remove();
$frmResponseField.removeClass('text-danger').addClass('text-success').html('<i class="icon-ok"></i> Wait while we send your message.');
$form[0].submit();
} else {
$responseField.removeClass('text-success').addClass('text-danger').html('<i class="dashicons dashicons-dismiss"></i> Oops! Try again.');
$btn.html(btnVal);
}
});
});
};
$('.ny-footer-contact-form').submit(function (e) {
e.preventDefault();
var $form = $(this);
var $responseField = $form.siblings('.response').removeClass('text-success text-danger').html('');
var command = $form.attr('data-submit').match(/return (\w+)\((.+)\)/i);
var fn = window[command[1]];
var $honeypot = $form.find('input.teddybear');
if ( fn(command[2]) && $honeypot.val() == '' ) {
getRecaptcha($form, $responseField);
} else {
$responseField.removeClass('text-success').addClass('text-danger').html('<i class="dashicons dashicons-dismiss"></i> There are missing fields.');
}
return false;
});
My impression is that since $form[0].submit() is not in any way filtered and doesn't trigger the submit event from jQuery, spammers are using that to submit the form and circunvent the reCaptcha.
What can I do?
A spammer will not execute your javascript code. They will simply post to the correct URL. Therefore you can't reliably validate anything on the client, you'll have to validate it on the server as well.
Bots can even does not run your JS - they just find forms in raw html and try to act as an user submitting the form. You have to validate reCaptcha value on server side, see here: https://developers.google.com/recaptcha/docs/php

Categories