This is my first time with spring boot. So, I have a simple index.html page, i go to it just through localhost:8080. I have some console.log() in my js under the html and they dont log a single thing. The api does work though, i tried it in postman and there is no problem. But it seems that the js doesnt recognize anything of the html. This is what the console.log() prints in the console:
As you can see they are empty. See my structure and my code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page</title>
</head>
<body>
<form id="loginform">
<div class="form-group">
<label for="Username">Username</label>
<input name="username" class="form-control" type="text" placeholder="Enter username" required>
</div>
<div class="form-group">
<label for="Password">Password</label>
<input name="password" class="form-control" type="password" placeholder="Password" required>
</div>
<button id="login">Login</button>
</form>
<script>
function login() {
var formData = new FormData(document.querySelector("#loginform"));
var encData = new URLSearchParams(formData.entries());
console.log(formData);
console.log(encData);
console.log(document.querySelector("#loginform"));
fetch("/authenticate", {method: 'POST', body: encData})
.then(function (response) {
if (response.ok) {
window.location.href = "/lingogame.html";
return response.json();
} else {
alert("Invalid Username or password");
}
})
.then(myJson => window.sessionStorage.setItem("myJWT", myJson.JWT))
.catch(error => console.log(error));
}
var loginButton = document.querySelector("#login")
if (loginButton) {
loginButton.addEventListener("click", login);
}
</script>
</body>
</html>
The problem may result from CSRF support of Spring Security. Check CSRF support is enabled or disabled, by default it is enabled by Spring Security. If enabled you must be send csrf_token with "X-CSRF-TOKEN" header with csrfToken value, otherwise it is not required.
Related
I am not worried about security, this is just a small project, which I am using only on my computer. I need to store a .txt file with data from a login form to the same location that the HTML file is. I don't think you can do it with javascript, but I don't know anything about PHP and I have tried many times to get this to work, but it isn't. Here is my code.
<form style="text-align: center;" action="./success.html" method="post">
<div class="form-group">
<label for="username">Username</label>
<input placeholder="Username" autocomplete="off" type="text" id="username" name="username"><br>
</div>
<div class="form-group">
<label for="password">Password</label>
<input placeholder="Password" autocomplete="off" type="password" id="password" name="password"><br><br>
</div>
<input id="button1" class="btn btn-success" type="submit" value="Sign Up">
<!-- When pressed, needs to store data in a data.txt file. -->
</form>
How would I be able to do this if I'm using this setup, and what would I need to change?
I'll just show you a quick example to get you started and create a JSON file with some data like:
{"username":"Lorem", "password":"ipsum"}
Rather than into .txt use a .json file. It's the today's most popular standard for storage and transmit of structured data.
Use AJAX to send a request and receive a response - without page refresh
Use json_encode the nifty PHP's file_put_content
Use JS's fetch ("POST") with the data being the FormData
Run the demo using php -S localhost:81 and open it in your browser:
save.php
<?php
if (
$_SERVER['REQUEST_METHOD'] === 'POST'
&& isset($_POST["username"])
&& isset($_POST["password"])
) {
$json = json_encode($_POST);
// Save JSON to file
file_put_contents("user.json", $json);
// Return some data back to the AJAX request.
echo $json;
// PS it's not wise to send passwords that way.
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="#!" type="image/x-icon">
<title>AJAX PHP - SAVE USER DATA </title>
</head>
<body>
<h1>User: <span data-username>Unknown</span></h1>
<form id="form-login" action="./save.php" method="post">
<div class="form-group">
<label>
<span>Username</span>
<input placeholder="Username" autocomplete="off" type="text" name="username">
</label>
</div>
<div class="form-group">
<label>
<span>Password</span>
<input placeholder="Password" autocomplete="off" type="password" name="password">
</label>
</div>
<input id="button1" class="btn btn-success" type="submit" value="Login">
</form>
<script>
const EL_formLogin = document.querySelector("#form-login");
EL_formLogin.addEventListener("submit", (ev) => {
ev.preventDefault(); // Stop default form submit - we'll use AJAX
fetch(EL_formLogin.action, {
method: 'POST',
body: new FormData(EL_formLogin),
}).then(res => res.json()).then(data => {
// Hide the form
EL_formLogin.hidden = true;
// Show the user name
document.querySelector("[data-username]").textContent = data.username;
});
});
</script>
</body>
</html>
DISCLAIMER!
Never store passwords in plaintext on your server files or database - and only send passwords over HTTPS.
So I'm building a web application with the option to be admin and add data to a JSON file, which will be displayed onto another HTML page (index).
Now is my question: how to do it. How to get the data from the form, parse it, and put it in a JSON file. And can it be done without Node.js
This is my current JSON-file
{"accounts": [
{"email": "example-mail#mail.com", "password2":"Duck123"},
{"email": "example-mail2#mail.com", "password2":"Cow123"},
{"email" : "example-mail3#mail.com", "password2": "Chicken123"}
]}
This is my "Admin" page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<title>ADMIN PAGE</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<form id="adminform" action="#" method="post">
<div class="form-group">
<label for="emailadress">Email Address</label>
<input type="email" class="form-control" id="emailadress" required autocomplete="false">
</div>
<div class="form-group">
<label for="password2">Password</label>
<input type="password" class="form-control" id="password2" required>
<input type="button" value="Show Password" readonly onclick="passwordShow()" autocomplete="false">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</body>
<script>
//show password on button click
function passwordShow() {
var x = document.getElementById("password2");
if (x.type === "password") {
x.type = "text";
} else {
x.type = "password";
}
}
</script>
</html>
If somebody knows how to do it, or has a tip, please let me know!
Direct writing to the filesystem can not be done from inside the Browser. However you have the possibility to create a "download" link, so that the user gets a notification that a file should be downloaded and can pick a location where to store that file.
Copied the following snippet from Stackoverflow: Download JSON object as a file from browser. You can use it to create exactly that download containing your json content.
function downloadObjectAsJson(exportObj, exportName){
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj));
var downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute("download", exportName + ".json");
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
}
I am building a Zendesk app that will post a variety of information to a webhook. Currently, I am running into two issues. The client.invoke() function says it is not a function in the console when the send email button is pressed. Additionally, sometimes the after the button is pressed, the app will successfully post to the webhook, other times it won't post at all. I cannot narrow down what is causing the discrepancies on when it posts. I'm unsure if this is related to the app I've built or an issue interacting with Zendesk.
Here is the app:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="main.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js"></script>
<script src="https://cdn.jsdelivr.net/handlebarsjs/4.0.8/handlebars.min.js"></script>
</head>
<body>
<script>
var client = ZAFClient.init();
client.invoke('resize', { width: '100%', height: '450px' });
client.get('ticket.brand.subdomain').then(
function(data) {
var subdomain = data['ticket.brand.subdomain'];
console.log('Zendesk Subdomain is ' + subdomain);
document.getElementById('subdomainform').value = subdomain;
}
);
client.get('ticket.organization.id').then(
function(data) {
var org_id = data['ticket.organization.id'];
console.log('Org id is ' + org_id);
document.getElementById('orgidform').value = org_id;
}
);
</script>
<form name="submissionForm">
<div class="formBox">
<label for="title">First Name</label>
<input type="text" id="firstName" placeholder="First Name"/>
</div>
<div class="formBox">
<label for="title">Last Name</label>
<input type="text" id="lastName" placeholder="Last Name"/>
</div>
<div class="formBox">
<label for="title">Email</label>
<input type="text" id="email" placeholder="Email"/>
</div>
<div class="formBox">
<select id="rescom">
<option value="residential">Residential</option>
<option value="commercial">Commercial</option>
</select>
</div>
<div class="formBox">
<button id="btn">Click to Send Email</button>
</div>
<div><p id="explain">The fields below are ready-only and required for submission. If you don't see them, please refresh the app.</p></div>
<div class="formBox">
<input type="text" id="subdomainform" readonly="readonly"/>
</div>
<div class="formBox">
<input type="text" id="orgidform" readonly="readonly"/>
</div>
</form>
<script>
let content = [];
const addDay1 = (ev)=>{
let information = {
id: Date.now(),
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
email: document.getElementById('email').value,
subdomain: document.getElementById('subdomainform').value,
orgid: document.getElementById('orgidform').value,
rescom: document.getElementById('rescom').value
}
content.push(content);
document.forms[0].reset();
const Url ='{PLACEHOLDER}';
$.ajax({
url: "{WEBHOOK URL}",
type: "POST",
dataType: 'json',
data: {information},
complete: function(){alert("Failure")}
});
}
document.addEventListener('DOMContentLoaded', ()=>{
document.getElementById('btn').addEventListener('click', addDay1);
});
</script>
</body>
</html>
What am I missing? Appreciate any and all help that can be provided.
This was solved my a community manager from Zendesk. See post below:
Make sure ZAFClient is fully registered before attempting to do
subsequent ZAFClient methods. Something like:
client.on('app.registered', e => {
client.get('ticket.brand.subdomain').then(
function(data) {
var subdomain = data['ticket.brand.subdomain'];
console.log('Zendesk Subdomain is ' + subdomain);
document.getElementById('subdomainform').value = subdomain;
}
);
client.get('ticket.organization').then(
function(data) {
var org_id = data['ticket.organization.id'];
console.log('Org id is ' + org_id);
document.getElementById('orgidform').value = org_id;
}
);
}) The "not a function in the console" error is caused from the app's HTML page being resubmitted again when you click the button. In
Zendesk Apps framework, the connection from the app (using
ZAFClient.init()) to the main agent window is done through parameters
that are passed to the app when the framework first loads it. You can
see this in your browser's Network tab if you look for something like
"iframe.html?origin=https%3A%2F%2Fyour_subdomain.zendesk.com&app_guid=ff7133010-abff-4f1c-a7bf-ff7133fff7133"
-- the origin and app_guid params are needed to make the connection. When you resubmit the page, those parameters no longer are passed on
the new page reload and the new call to ZAFClient.init() doesn't
successfully initialize. Thus leading the error when the now invalid
'client' object is attempting to be used to call 'invoke'. You have to
treat these app pages like single-page apps.
Phew! All that said -- you can still use HTML functionality,
just don't have it resubmit the entire page when the button is
pressed. You can do this by adding type="button" to the button tag.
Click to Send Email
See also: HTML button to NOT submit form
Hope this gets you on your way!
I have an ASP.NET MVC project and currently I am using ViewData["ResultMessage"] to show the result of a form (which is done after the user submits & refreshes the page).
I want to do it right after he clicks submit (without refreshing the page). So I have to use Javascript for that, which I am new with. No experience what so ever.
How my form looks like is this:
<form id="contactForm" method="post" action="..">
<div class="field half first">
<label for="Name">Name</label>
<input type="text" name="Name" id="Name" placeholder="Your name" required />
</div>
<div class="field half">
<label for="Email">Email</label>
<input type="email" name="Email" id="Email" placeholder="Your email" required />
</div>
<div class="field">
<label for="Message">Message</label>
<textarea name="Message" id="Message" rows="5" placeholder="Your message" required minlength="20"></textarea>
</div>
<input type="submit" value="Send Message" />
<p>#ViewData["ContactActionResult"]</p>
</form>
You can see the result is displayed with Razor using ViewData. Now I want to do it without refreshing the page and learn JS on the way.
What I have tried so far:
$(function () {
$("button").click(function (e) {
e.preventDefault()
$.ajax({
type: "POST",
url: "/Receiver",
data: car,
datatype: "html",
success: function (data) {
alert("Congratulations, it worked!");
$('#contactForm').html(data);
},
error: function(data) {
alert("Failed.");
}
});
});
});
But I am not sure if I did something wrong or simply not implementing it right. I have the above function inside <script> here </script> in my HTML page. Nothing happens when I click the submit button on the form.
If it is an ajax call, It is best if you return a JSON response . You can use the Request.IsAjaxRequest() to determine whether the request is normal form request or ajax call.
You should also consider using to the PRG pattern. After successfully saving, you should do a redirect to a GET action where you can render a view, instead of returning to the same view with a viewbag message. If you want to pass some message to the new view/action, use TempData instead of ViewData.
[HttpPost]
public ActionResult Receiver(string name, string Email)
{
// Your existing code to save
if(Request.IsAjaxRequest())
{
return Json(new { status = "success", message = "Created successfully" });
}
// Normal form submit. So let's follow PRG pattern
TempData["ResultMessage"] = "Created successfully";
return RedirectToAction("Index");
}
You can also put a try/catch and return a json like this for error usecase
return Json(new { status = "error", message = "some serious error" });
In Index action/view, you can read TempData["ResultMessage"] and display to user.
Now, for the ajax usecase, in your current view, you can add a div to show the message
<form id="contactForm" method="post" asp-action="Receiver">
<div id="msg"></div>
<div class="field half first">
<label for="Name">Name</label>
<input type="text" name="Name" id="Name" placeholder="Your name" required />
</div>
<div class="field half">
<label for="Email">Email</label>
<input type="email" name="Email" id="Email" required />
</div>
<div class="field">
<label for="Message">Message</label>
<textarea name="Message" id="Message" rows="5"
placeholder="Your message" required minlength="20"></textarea>
</div>
<input type="submit" value="Send Message" />
</form>
and now in your ajax call's success callback, check the json response coming back from server and show the message property as needed. If you are putting the script inside the razor view file, make sure you are putting it inside a Scripts section so that it will be evaluated in the proper order (After jQuery is loaded, assuming you load jQuery before calling RenderSection("scripts") inside the layout)
#section Scripts
{
<script>
$(function (){
$("#contactForm").submit(function (e){
e.preventDefault()
$.ajax({
type: "POST",
url: $(this).attr("action"),
data: car,
success: function (data){
if (data.status === "success")
{
$('#msg').html(message);
}
//to do : handle statuss=="error" as needed
},
error: function (data)
{
alert("Failed.");
}
});
});
});
</script>
}
For asp.net core, you can write a IsAjaxRequest method in your base controller and use that. jQuery will add X-Requested-With header with value XMLHttpRequest for your ajax calls.
protected bool IsAjaxRequest()
{
return Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
We have a form that should post data to an external domain. We are aware of the cross-domain limitations, therefore we want to use JSONP.
All parts are working fine, except for the part that should prevent a default form submission that reloads the page. Below is the form.
The html page:
<html lang="en">
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="https://gateway.wildfx.com/test.js"></script>
</head>
<body>
<form method="POST" id="wild">
<fieldset>
<label for="email">Your email:</label>
<input type="text" name="email" id="wild">
<p class="wild_err">invalid</p>
<p>
<input type="hidden" id="wild_v" name="v" value="test2">
<input type="hidden" id="wild_l" name="l" value="">
<input type="hidden" id="wild_i" name="i" value="identifier">
<input type="hidden" id="wild_s" name="s" value="10612">
<input type="submit" id="wild_button" value="Check">
</p>
</fieldset>
</form>
</body>
</html>
Below is the Javascript. However, if the wild form is submitted, the page reloads instead of transfering the data with JSONp. In addition even the submission2 log isn't logged.
If tried to replace the .submit() with .click for the from button with correct ID but it isn't working either. What is wrong with the script?
function isValidEmailAddress(emailAddress) {
var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
return pattern.test(emailAddress);
};
console.log('submission1');
$("#wild").submit(function(e) {
console.log('submission2');
e.preventDefault();
if (isValidEmailAddress(e["e"])) {
var e = {};
e["e"] = $("#wild_email").val();
e["v"] = $("#wild_v").val();
e["i"] = $("#wild_i").val();
e["s"] = $("#wild_s").val();
e["l"] = $("#wild_l").val();
(function() {
var wildAPI = "https://gateway.wildfx.com/testjsonp.php?jsoncallback=?";
$.getJSON( wildAPI, {
tagmode: e,
format: "json"
})
.done(function( data ) {
$(".wild_message_container").text('Success. you are in');
setTimeout(function() {
$("#wildnotifier-container").hide();
$("#wildnotifier-overlay").hide();
}, 5000);
});
})();
} else {
$(".wild_error").show();
$("#wild_email").addClass("wild_input_error");
}
});
You load jQuery
You load your script
Your script tries to add an event handler to the form
You add the form to your page
Step 3 fails because the form doesn't exist. Move the script so it is after the form. (Or put it in a function and call it with the DOM is ready).