When my login credentials are prefilled by my browser (chrome) my fetch function doesn't send the values
html
<div class='login-frame'>
<h3>Bienvenue</h3>
<div class='form'>
<div class='input-handler'>
<label for='login'>Login</label>
<input type='text' id='login' name='login' autocomplete='on'>
</div>
<br>
<div class='input-handler'>
<label for='pass'>Mot-de-passe</label>
<input type='password' id='pass' name='pass' autocomplete='on'>
</div>
<br>
<button id='loginbutton'>CONNEXION</button>
</div>
</div>
JS
window.onload = function() {
var pass = document.getElementById('pass'),
login = document.getElementById('login'),
loginButton = document.getElementById('loginbutton');
loginbutton.onclick = (e)=> {
var creds = {
login: login.value,
pass: pass.value
}
fetch('functions/log.php', {
method: "POST",
header: {"Content-type": "application/json; charset=UTF-8"},
body: JSON.stringify(creds)
});
}
PHP
$pos = json_decode(file_get_contents('php://input', true));
echo var_dump($pos);
If I type anything, it returns
object(stdClass)#3 (2) {
["login"]=>
string(3) "qfz"
["pass"]=>
string(5) "zfqzf"
}
If I use the browser prefill, it returns
NULL
It was a mistake,
as #CBroe said, it was a security problem. Changing my html to a proper form make it works as it should
<form class='login-frame' method='post' action='#'>
<div class='login-logo'><img src='bs/img/logo_b.svg'></div>
<h3>Bienvenue</h3>
<div class='form'>
<div class='input-handler'>
<label for='login'>Login</label>
<input type='text' id='login' name='login' autocomplete='on'>
</div>
<br>
<div class='input-handler'>
<label for='pass'>Mot-de-passe</label>
<input type='password' id='pass' name='pass' autocomplete='on'>
</div>
<br>
<button type='submit' id='loginbutton'>CONNEXION</button>
</div>
</form>
Related
I can't get the values of these three fields; it only returns an empty value (a space).
The ids are correctly set in the form.
<script>
const data = {
id: document.getElementById('idbook').value,
name: document.getElementById('namebook').value,
price: document.getElementById('pricebook').value
};
function myFunction(){
const http = new easyHTTP;
http.put('https://otg0gf6qw5.execute-api.us-east-2.amazonaws.com/books',
data, function(err, post){
if(err) {
console.log(err);
} else {
console.log(post);
}
});
</script>
<!DOCTYPE html>
<html>
<body>
<div class="container">
<form method="post" id="save" action="javascript:myFunction()">
<h1>Insert Book</h1>
<div class="field">
<label for="id">ID Book:</label>
<input type="text" id="idbook" name="id"/>
<small></small>
</div>
<div class="field">
<label for="id">Name Book:</label>
<input type="text" id="namebook" name="nameBook"/>
<small></small>
</div>
<div class="field">
<label for="id">Price Book:</label>
<input type="text" id="pricebook" name="priceBook"/>
<small></small>
</div>
<div class="field">
<button type="submit" class="full">SAVE BOOK</button>
</div>
</form>
</div>
When I enter the values, and click on SAVE I get an empty json, i.e .:
{"id":"","name":"","price":""}
with error:
"One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: id"
The problem is that you are getting the values from the input fields as soon as the script runs, so you will get empty strings because the inputs at that point are empty.
To get the input values after the form is submitted, put the data variable inside the myFunction() method, it's important to read the values right before sending the data.
Example
<script>
function myFunction() {
const data = {
id: document.getElementById('idbook').value,
name: document.getElementById('namebook').value,
price: document.getElementById('pricebook').value
};
const http = new easyHTTP;
http.put('https://otg0gf6qw5.execute-api.us-east-2.amazonaws.com/books', data, function(err, post) {
if(err) {
console.log(err);
} else {
console.log(post);
}
});
};
</script>
I don't know if this is what you mean, but I did let the data save in the console log when you press submit
<div class="container">
<form method="post" id="save" action="javascript:myFunction()">
<h1>Insert Book</h1>
<div class="field">
<label for="id">ID Book:</label>
<input type="text" id="idbook" name="id"/>
<small></small>
</div>
<div class="field">
<label for="id">Name Book:</label>
<input type="text" id="namebook" name="nameBook"/>
<small></small>
</div>
<div class="field">
<label for="id">Price Book:</label>
<input type="text" id="pricebook" name="priceBook"/>
<small></small>
</div>
<div class="field">
<button type="submit" class="full">SAVE BOOK</button>
</div>
</form>
<script>
function myFunction(){
const data = {
id: document.getElementById('idbook').value,
name: document.getElementById('namebook').value,
price: document.getElementById('pricebook').value
};
console.log(data);
}
</script>
</div></body></html>
I have built a login form using below code.
I am using a CGI version CGIDEV2 native to IBMi series. I am Validating the userid and password in the flower.cgi program. If the userid and password are validated, I am loading another html file to show a table. This works flawlessly.
If the userid and password are wrong, I am returning out of the program without writing anything. This results in a 500 Internal server error.
I want to capture this 500 Internal server error using javascript. I have tried using ajax but was not successful as I have limited understanding of javascript.
What could be the best way to achieve this?
<form method="POST" action="/nature/flower.cgi">
<!-- Username input -->
<div class="form-outline mb-4">
<input type="text" name="userid" id="form3Example3" class="form-control form-control-lg" style="text-transform:uppercase" placeholder="Enter a valid IBMi UserID" />
<label class="form-label" for="form3Example3">IBMi UserID</label>
</div>
<!-- Password input -->
<div class="form-outline mb-3">
<input type="password" name="passwd" id="form3Example4" class="form-control form-control-lg" placeholder="Enter password" />
<label class="form-label" for="form3Example4">Password</label>
<br>
</div>
<div class="d-flex justify-content-between align-items-center">
<!-- Checkbox -->
<div class="form-check mb-0">
<input class="form-check-input me-2" type="checkbox" value="" id="form2Example3" />
<label class="form-check-label" for="form2Example3">Remember me</label>
</div>
Forgot password?
</div>
<div class="text-center text-lg-start mt-4 pt-2">
<button type="submit" class="btn btn-primary btn-lg" style="padding-left: 2.5rem; padding-right: 2.5rem;">Login</button>
</div>
</form>
You can't capture an error from a URL the browser is navigating to.
The only way you could would be if you replaced the normal form submission with Ajax (in which the request is made and the response processed with JavaScript).
Generally speaking, if you were going to do that you would also want to rewrite the CGI program so it output structured data (e.g. as JSON) instead of semantic data (HTML).
It would not be a particularly small undertaking. You said you had tried it, which probably gives you some idea of the scope of it (i.e. far outside the scope of a Stackoverflow question).
A more sensible approach would almost certainly be to track down the cause of the 500 error and change the CGI program so it would capture it itself.
yes, the fetch api in javascript can post form data to your CGI program and check for the 500 response code. Then the web page can either display an error message or run the form.submit() method to actually submit the form up to the server.
Here is PHP and javascript code that simulates the whole thing. Should work similar with CGI. The key is you change the form submit button from type 'submit' to type 'button'. That way, clicking the submit button can run javascript code instead of the form being submitted to the server.
<?php
// site/tester/php/submit-form.php
header("Content-type: text/html; charset:utf-8;");
?>
<?php
$userid = isset($_POST["userid"]) ? $_POST["userid"]: '' ;
$passwd = isset($_POST["passwd"]) ? $_POST["passwd"]: '' ;
$remember = isset($_POST["remember"]) ? $_POST["remember"]: 'off' ;
if ( strtolower($userid) == 'alex')
{
http_response_code( 500 );
echo "$userid - invalid user name";
exit ;
}
?>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row mt-3">
<div class="col-auto">
<h1>submit form demo</h1>
</div>
</div>
</div>
<div class="container">
<div class="row mt-3">
<div class="col-4">
<form method="POST" id="main-form" action="./index.php">
<!-- Username input -->
<div class="form-outline mb-4">
<input type="text" name="userid" id="userid"
class="form-control form-control-lg"
value="<?= $userid ?>"
style="text-transform:uppercase" placeholder="Enter a valid IBMi UserID" />
<label class="form-label" for="userid">IBMi UserID</label>
</div>
<!-- Password input -->
<div class="form-outline mb-3">
<input type="password" name="passwd" id="passwd" class="form-control form-control-lg"
placeholder="Enter password" />
<label class="form-label" for="passwd">Password</label>
<br>
</div>
<div class="d-flex justify-content-between align-items-center">
<!-- Checkbox -->
<div class="form-check mb-0">
<input class="form-check-input me-2" type="checkbox"
<?= ($remember == 'on' ? 'checked' : '' ) ?>
name="remember" id="form2Example3" />
<label class="form-check-label" for="form2Example3">Remember me</label>
</div>
Forgot password?
</div>
<div class="text-center text-lg-start mt-4 pt-2">
<button id="login-button" type="button" class="btn btn-primary btn-lg"
style="padding-left: 2.5rem; padding-right: 2.5rem;">
Login</button>
</div>
</form>
</div>
</div>
<div id="login-errmsg-collapse" class="collapse row mt-3">
<div class="alert alert-warning" role="alert">
<p id="login-errmsg">Invalid login. User name does not exist.</p>
</div>
</div>
</div>
<div class="container">
<div class="row mt-3">
<div class="col-auto">
<p>userid: <?= $userid ?></p>
<p>passwd: <?= $passwd ?></p>
<p>remember: <?= $remember ?></p>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="./app.js"></script>
</body>
// ./submit-form/app.js
// enable the submit button click handler.
{
const elem = document.getElementById('login-button');
elem.addEventListener('click', event =>
{
login_click();
});
}
// -------------------------------- login_errmsg_show ---------------------
function login_errmsg_show( respText )
{
// show the response message in the bootstrap collapse alert box.
{
const elem = document.getElementById('login-errmsg') ;
elem.textContent = respText ;
}
const myCollapse = document.getElementById('login-errmsg-collapse')
const bsCollapse = new bootstrap.Collapse(myCollapse, {
toggle: false
});
bsCollapse.show( ) ;
}
// -------------------------------- login_click -------------------
async function login_click()
{
const elem = document.getElementById('main-form');
if (elem)
{
const {respText, status} = await webpage_post( ) ;
if ( status != '500')
{
elem.submit();
}
else
{
login_errmsg_show( respText ) ;
}
}
}
// --------------------------------- webpage_post -----------------------
async function webpage_post( )
{
const userid = document.getElementById('userid').value ;
const passwd = document.getElementById('passwd').value ;
const remember = 'on' ;
const url = "./index.php";
const params = { userid, passwd, remember } ;
const query = object_toQueryString(params);
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: query
});
const respText = await response.text();
const status = response.status ;
console.log( respText ) ;
return {respText, status} ;
}
// ------------------------- object_toQueryString ------------------------
function object_toQueryString(obj)
{
const qs = Object.keys(obj)
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]))
.join('&');
return qs;
}
I have the following html snippit from my view and js code to handel the form request.
$('#quick-enquiry').on('submit', function(e) {
e.preventDefault();
$(".submit").prop("disabled", true);
data = $(this).serialize();
action = $(this).attr('action');
$.ajax({
type: 'POST',
url: action,
data: data,
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
},
success: function(data) {
if ($.isEmptyObject(data.error)) {
$("#quick-enquiry").trigger("reset");
$('.print-error-msg').find('ul').empty();
$('.print-error-msg').css('display', 'block');
$("#response-msg").toggleClass('uk-alert-danger uk-alert-success');
$('.print-error-msg').find('ul').append("<li>" + data.success + "</li>");
setTimeout(function() {
$('.print-error-msg').fadeOut();
$(".submit").prop("disabled", false);
UIkit.modal("#modal-quick-enquiry").hide();
}, 3000);
} else {
printMessageErrors(data.error);
}
}
});
});
function printMessageErrors(msg) {
$('.print-error-msg').find('ul').empty();
$('.print-error-msg').css('display', 'block');
$.each(msg, function(key, value) {
$('.print-error-msg').find('ul').append("<li>" + value + "</li>");
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.26/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.26/css/uikit.min.css" rel="stylesheet" />
<form action="{{ route('frontend-postEnquiry') }}" method="POST" id="quick-enquiry">
<input type="hidden" id="tour-id" value="1">
<div class="uk-margin">
<label class="uk-form-label" for="form-stacked-text">Full Name</label>
<div class="uk-form-controls">
<input class="uk-input uk-form-width-large" type="text" placeholder="Full Name" id="fullName" name="fullName">
</div>
</div>
<div class="uk-margin">
<label class="uk-form-label" for="form-stacked-text">Email</label>
<div class="uk-form-controls">
<input class="uk-input uk-form-width-large" type="email" placeholder="Email" id="email" name="email">
</div>
</div>
<div class="uk-margin">
<label class="uk-form-label" for="form-stacked-text">Message</label>
<div class="uk-form-controls">
<textarea class="uk-textarea uk-form-width-large" rows="4" placeholder="Some Message...." id="enquiryMessage" name="enquiryMessage"></textarea>
</div>
</div>
<p class="uk-text-right">
<button class="uk-modal-close-default" type="button" uk-close></button>
<button class="uk-button uk-button-primary submit uk-width-1-1" type="submit">Send</button>
</p>
</form>
With the above code I'm getting
419
Sorry, your session has expired. Please refresh and try again.
I've set CSRF-TOKEN in ajax and in head section also, but seems like my js code is not picking up csrf token.
I would be very thankful if anyone could highlight the mistake I've made above.
Try using this:
{{ csrf_field() }} instead of #csrf
419 error is mostly because of CSRF token issues.
$('.button-save').click(function(b){
b.preventDefault();
var title = $('#title').val(),
category = $('#category').val(),
file = $('#file').val(),
short_content = tinyMCE.get('#short_content').getContent(),
content = tinyMCE.get('#content').getContent(),
date = $('#date').val(),
language = $('#language').val();
alert(short_content);
$.ajax({
type: 'POST',
url: '/admin/save',
data: {
title:title,
category:category,
file:file,
short_content:short_content,
content:content,
date:date,
language:language
},
success: function(data){
$('.adm-notification').html(data);
}
});
});
As you see there are two textareas (short_content,content); I tried to get them via tinyMCE.get('#content').getContent(). But i'm getting the error
Uncaught TypeError: Cannot call method 'getContent' of undefined
HTML code
<form action=\"\" method=\"post\">
<div class=\"element\">
<label for=\"name\">Page title <span class=\"red\">(required)</span></label>
<input id=\"title\" name=\"name\" value=".$edit['title']." class=\"text\" />
</div>
<div class=\"element\">
<label for=\"category\">Category <span class=\"red\">(required)</span></label>
<input id=\"category\" name=\"category\" value=".$edit['category']." class=\"text\" />
</div>
<div class=\"element\">
<label for=\"attach\">Attachments</label>
<input type=\"file\" id=\"file\" name=\"attach\" />
</div>
<div class=\"element\">
<label for=\"short-content\">Short content <span class=\"red\">(required)</span></label>
<textarea name=\"short_content\" id=\"short_content\" class=\"textarea\" rows=\"10\">".$edit['short_content']."</textarea>
</div>
<div class=\"element\">
<label for=\"content\">Long content <span class=\"red\">(required)</span></label>
<textarea name=\"content\" id=\"long_content\" class=\"textarea\" rows=\"10\">".$edit['content']."</textarea>
</div>
<div class=\"element\">
<label for=\"date\">Date <span class=\"red\">(required)</span></label>
<input id=\"date\" name=\"date\" class=\"text\" value=".$edit['date']." />
</div>
<div class=\"element\">
<label for=\"language\">Language <span class=\"red\">(required)</span></label>
<input id=\"language\" name=\"language\" value=".$edit['lang']." class=\"text\" />
</div>
<div class=\"entry\">
<button type=\"submit\" id=\"button-save\" class=\"add button-save\">Save page</button>
</div>
</form>
How to fix?
You need to supply the id of the textarea, without the #.
tinyMCE.get('long_content').getContent()
tinyMCE.get('short_content').getContent()
btw, you need to decide whether you want to submit the form or read out the value with JavaScript and then send it to the server. Here a solution reading it out with JS:
<script type="text/javascript">
tinyMCE.init({
mode : "textareas"
});
$(function(){
$('#button-save').click(function(){
console.log("ok");
var short_content = tinyMCE.get('short_content').getContent();
var content = tinyMCE.get('long_content').getContent();
alert(short_content);
alert(content);
});
});
</script>
<textarea name="short_content" id="short_content" >'short_content'</textarea>
<textarea name="long_content" id="long_content" >'content'</textarea>
<button id="button-save" class="add button-save">Save page</button>
Same as a working fiddle.
I am trying to send an e-mail after an ajax call has been successfully completed. I do not have access to the file that I am making the AJAX call to.
I am preventing the first submit, making the ajax call and submitting the form again upon competition. When doing this, I can't seem to figure out why I have to press the submit button twice for the email to be sent.
Here is my code:
"use strict";
var submitted = '';
/* Send info to the portal */
jQuery(function($) {
$('#quote').submit(function(e){
var firstName = $('#firstName').val(),
lastName = $('#lastName').val(),
email = $('#email').val(),
phone = $('#primaryPhone').val(),
weight = $('#weight').val(),
origin = $('#originPostalCode').val(),
destination = $('#destinationPostalCode').val(),
notes = $('#whatsTransported').val()
if( submitted != 1 )
{
e.preventDefault();
$.ajax({
type: "POST",
url: "https://somewhere.on/the/internet.php",
crossDomain: true,
dataType: "json",
data: {"key": "my secret key","first": firstName, "last": lastName, "email": email, "phone": phone, "weight": weight, "origin_postal": origin, "dest_country": destination, "note": notes }
})
.done(function(data){
if(data[1][0][0] == 2)
{
$('.alert').append( data[1][0][1].message ).addClass('alert-error').show();
} else if(data[1][0][0] == 0) {
console.log("Made it.");
$('#quote #submit').submit();
} else {
$('.alert').append( "Appologies, it seems like something went wrong. Please, <strong>call (877) 419-5523</strong> for immediate assistance or a free quote.");
}
})
.fail(function(data) { console.log(data); });
}
submitted = '1';
});
});
Here is the form HTML
<form action="<?php echo bloginfo($show='template_url').'/includes/form-email.php'; ?>" class="span6 offset1" id="quote" method="post">
<div class="row formRow">
<div class="firstName span3">
<label for="firstName"><?php _e('First Name:','StreamlinedService'); ?></label>
<input type="text" name="firstName" id="firstName">
</div>
<div class="lastName span3">
<label for="lastName"><?php _e('Last Name:','StreamlinedService'); ?></label>
<input type="text" name="lastName" id="lastName">
</div>
</div>
<div class="row formRow">
<div class="email span3">
<label for="email"><?php _e('Email Address:','StreamlinedService'); ?></label>
<input type="text" name="email" id="email">
</div>
<div class="primaryPhone span3">
<label for="primaryPhone"><?php _e('Phone Number:','StreamlinedService'); ?></label>
<input type="text" name="primaryPhone" id="primaryPhone">
</div>
</div>
<div class="row formRow">
<div class="weight span2">
<label for="weight"><?php _e('Weight (lbs):','StreamlinedService'); ?></label>
<input type="text" name="weight" id="weight">
</div>
</div>
<div class="row formRow">
<div class="originPostalCode span3">
<label for="originPostalCode"><?php _e('Origin:','StreamlinedService'); ?></label>
<input type="text" name="originPostalCode" id="originPostalCode">
</div>
<div class="destinationPostalCode span3">
<label for="destinationPostalCode"><?php _e('Destination:','StreamlinedService'); ?></label>
<input type="text" name="destinationPostalCode" id="destinationPostalCode">
</div>
</div>
<div class="row">
<div class="whatsTransported span6">
<label for="whatsTransported"><?php _e('What can we help you transport?','StreamlinedService'); ?></label>
<textarea name="whatsTransported" id="whatsTransported" rows="5"></textarea>
</div>
<input type="hidden" name="formType" value="quote" />
<input type="hidden" name="siteReferer" value="<?php echo $blog_id ?>">
<input type="submit" id="submit" name="submit" value="<?php _e('Get Freight Quote','StreamlinedService') ?>" class="btn btn-primary btn-large span3 offset3" style="float:right;">
</div>
</form>
My question is two-fold: Is there a more efficient way to do this? If not, why isn't this working?
Just use the .submit directly on the form node (note the [0])
$('#quote #submit').submit();
becomes
$('#quote')[0].submit();
this bypasses the jQuery bound event and forces a postback.
You use the wrong approach to Jquery
You miss the key : Write Less Do More, the heart of JQuery.
Anyway try this:
"use strict";
/* Send info to the portal */
jQuery(function($) {
$('#quote').submit(function(e){
var tis = $(this);
$.ajax({
type: "POST",
url: "https://somewhere.on/the/internet.php",
cache: true,
dataType: "json",
data: tis.serialize(),
success: function(data){
if(data[1][0][0] == 2){
$('.alert').append( data[1][0][1].message ).addClass('alert-error').show();
} else if(data[1][0][0] == 0) {
console.log("Made it.");
$('#quote #submit').submit();
} else {
$('.alert').append( "Appologies, it seems like something went wrong. Please, <strong>call (877) 419-5523</strong> for immediate assistance or a free quote.");
}
},
error: function(data){console.log(data);}
});
e.stroPropagation();
e.preventDefault();
});
});
Last thin.. you CAN'T request a remote page that's not hosted on the same domain of the script.. For that ther's This answer