I fill in a form in html and then submit it.
At first the client validates the data (e.g if the eula checkbox is accepted) and after the client sends the data to the server.
The server checks also the data returns a status code to me.
How can I get this status code from the server?
Here are some example snippets
HTML
<form name="newsletter" method="post" action="/api/newsletter" onsubmit="if(!validate()){return false;} else tryToFetch();">
<input name="name" type="text" id="name"/>
<input name="eula" type="checkbox" id="eula"/>
<input type="submit" name="submit"/> </form>
client js:
function validate() {
if (this.eula.checked == false) { alert ('EULA NOT ACCEPTED'); return false; } else {
return true; }
}
tryToFetch
function tryToFetch(){
fetch('http://localhost:3000/api/newsletter')
.then(function(response) {
console.log(response.status ) ;
});
}
Server.js
app.post('/api/newsletter', urlencodedParser ,function (request, response) {
//Just check some data...
response.statusCode = 999;
response.send('999');
});
Now how can I get the status code 999 in the browser and handle it?
Is it even possible todo only using js?
As written in Fetch documentation :
"The fetch specification differs from jQuery.ajax() in two main ways:
The Promise returned from fetch()won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing."
So maybe this is causing your problem ? Have you tried using default XMLHttpRequest.
Related
I have a submit form, after checking the captcha v3, I need to send the form with the same values. how to do this after receiving the token from the captcha?
With the code below, either a human or a bot outputs to the browser console, but does not redirect to the desired page
.then(result => {
if (result['om_score'] >= 0.5) {
console.log('Human')
} else {
console.log('Bot')
}
});
If i use window.location = "mail.php"; insted of console.log it send empty request
My goal is that the redirect would be to the <from> action with the entered values.
You can use JS to submit the form. Suppose you have the following form:
<form id="myform" action="mail.php" method="post">
....
</form>
You can use JS to submit it:
....
.then(result => {
if (result['om_score'] >= 0.5) {
console.log('Human')
document.getElementById("myform").submit();
} else {
console.log('Bot')
}
});
As a side note, you shouldn't be checking the Captcha client-side because it can easily be spoofed.
I am trying to send a String within Javascript to my Server. I made it create a cookie and right now I would like it to do stuff (for now: a simple echo). This is my button-function (I am using Bokeh):
const d = s.data;
var clustOut = "Nevermind the real input";
if (numberOfColors.length >= 2) {
localStorage.setItem("input", clustOut);
document.cookie = ('clustOut=' + clustOut + ';max-age=10368000;' + ';path=/');
window.location.href = "/php-scripts/post_cluster.php";
//alert(numberOfColors.length + "\\n" + clustOut);
//alert(d["x"] + d["y"] + d["color"]);
} else {
alert ("You have to assign the points to at least two clusters!");
}
My PHP-Files should simply echo:
<?php
$clustOut = $_COOKIE['clustOut'];
echo $clustOut;
?>
I am pretty sure that window.location.href = "/php-scripts/post_cluster.php"; might be the wrong command for a submit. What can I do to make my PHP-Script get the Cookie that I just set?
Sending data with the Fetch API.
The client and server can communicate with each other with the HTTP protocol. Whenever you load a webpage a HTTP request is send to the server and a response is send back to the client. You can make your own requests and talk to the server through the same protocol with the Fetch API.
You send the data to the server and wait for a response to come back. This way you can check what the server received and maybe do something with the response you got back.
let data = {
clustOut: "Nevermind the real input"
};
fetch('/php-scripts/post_cluster.php', {
method: 'POST',
body: JSON.stringify(data)
}).then(response => {
if (response.status === 200 && response.ok) {
return response.text();
}
}).then(message => {
console.log(message);
});
Sending data with XMLHttpRequest (IE10+)
For browsers that don't support the Fetch API fall back to the older XMLHttpRequest. It does the same thing, but is written differently.
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (this.status === 200) {
console.log(this.responseText);
}
}
xhr.open('POST', '/php-scripts/post_cluster.php');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(JSON.stringify(data));
Sending data with the a form.
A more analogue approach would be to use a <form> element with the action attribute pointing towards your PHP script. This will also send a request to the PHP file while reloading the page. However, reading out the response works differently as you need to display the response on the page during rendering to see the outcome.
<form method="POST" action="/php-scripts/post_cluster.php">
<input type="hidden" name="clustOut" value="Nevermind the real input">
<button type="submit">Send</button>
</form>
Receiving data on server
Because in the examples above we've used the POST method to send our data, we'll need to access the global $_POST variable in PHP to read out the data that has been send. The value that is being returned or echoed will be send back in the response to the client.
<?php
$clust_out = isset( $_POST[ 'clustOut' ] ) ? $_POST[ 'clustOut' ] : '';
return $clust_out . ' has been received';
?>
I have a really simple login form that I want to check if the credentials are right (so I don't have to reload a page if the credentials are wrong) before submitting the form.
The problem I'm running into is the response from the AJAX call. When the program decides that the user has supplied the correct credentials, this code works like a charm. In addition, when performing the two checks prior to the AJAX call (whether the user filled in the password input field or if the username is valid), the code works perfectly. It returns an error message and returns the false boolean value, preventing the form from submitting. But, when the response from the server comes back and it is found that the credentials are not correct, the error message displays, but the page also reloads (therein displaying an additional error message). Why is the form still submitting, even though I'm returning false? I've checked the JavaScript console, there are no errors. I've also tried inverting the if statement, checking if ajax.responseText === "true", to the same result. I've tried adding a return false beneath the ajax.onreadystatechange call, but that just prevents the form from submitting at all (regardless of the response from the server).
Here is the form code:
<form method="POST" action="/afton/" onsubmit="return checkForm()">
<label for="username">Username:</label>
<input type='text' id='username' name='username' placeholder='Enter username...' required>
<label for="password">Password:</label>
<input type='password' id='password' name='password' placeholder='Enter password...' required>
<div class="form-buttons">
<button type='submit' name='action' id="loginButton" value='login'>Login</button>
<button type='button' id='register'>Register</button>
</div>
</form>
Here is the js function:
// Function that checks whether the user supplied correct credentials
function checkForm() {
// Get the password provided and the server message div on the page
const messageBox = document.getElementById("server-message");
const password = document.getElementById("password").value;
// If password is blank, return error message and return false
if (password === "") {
messageBox.innerHTML = "<p class='badMessage'>Please fill in the password!</p>"
return false;
}
// If the username input tag doesn't contain the 'goodBorder' class received upon validation of username, return error and false
if (!usernameInput.classList.contains("goodBorder")) {
messageBox.innerHTML = "<p class='badMessage'>Please provide a valid username!</p>"
return false;
}
// AJAX call that posts the info via JSON to check
const ajax = new XMLHttpRequest();
ajax.open("POST", "index.php?action=ajaxLogCheck", true);
ajax.setRequestHeader("Content-type", "application/json");
ajax.send(JSON.stringify({"username":usernameInput.value, "password":password}));
// Handles the AJAX response
ajax.onreadystatechange = function () {
if (ajax.readyState === 4 && ajax.status === 200) {
if (ajax.responseText !== "true") {
messageBox.innerHTML = ajax.responseText;
return false;
}
return true
}
}
}
And here is the PHP code that handles the AJAX:
// Get posted JSON encoded data
$data = json_decode(trim(file_get_contents("php://input")), true);
// Filter and sanitize the supplied username and password
$username = filter_var($data['username'], FILTER_SANITIZE_STRING);
$password = filter_var($data['password'], FILTER_SANITIZE_STRING);
// Get user data by the username and check the username against the password
$userData = getClient($username);
$hashCheck = password_verify($password, $userData['password']);
// Check response from the hashCheck and return the result
if ($hashCheck) {
echo "true";
exit;
}
logAtt($username, $_SERVER['REMOTE_ADDR'], false, getBrowser($_SERVER['HTTP_USER_AGENT']));
sleep(0.5);
$rands = array("Sorry, the username and/or password doesn't match our database. Please try again.", "Sorry, we don't recognize those login credentials. Please try again.", "Sorry, that login was incorrect. Please try again.", "Incorrect, please try again");
$randResult = array_rand(array_flip($rands));
echo "<p class='badMessage'>$randResult</p>";
// Just the point in AJAX function where you were returning True or
// False...Just Assign RESULT = 0 for False and
// RESULT = 1 for True
// .....SUppose You password matches so you were returning True..
// Dont do that...Instead Just Assign RESULT = 0 in that place and
// and out of the ajax Block paste this 'return Boolean(RESULT)'
// if RESULT = 0 then it will return False else it will return True
// Function that checks whether the user supplied correct credentials
function checkForm()
{
// Initialize a Variable Here Say RESULT
var RESULT = 0;
if (password === "")
{
RESULT = 0;
}
else if (!usernameInput.classList.contains("goodBorder"))
{
messageBox.innerHTML = "<p class='badMessage'>Please provide a valid username!</p>"
RESULT = 0;
}
// After this Put the ajax function and if you want to return False
// then simply assign RESULT = 0 instead of 'return false' else assign
// RESULT = 1 instead of 'return true'
return Booelan(RESULT);
// THis line is main Part this is returned by checkForm() function
}
// If I am still not clear, then I'll be happy to explain it on Google Meet.! :)
On the server-side I have a transaction which returns a JsonResult:
public JsonResult DoStuff(Guid id, string userInputText)
{
var product = _repository.Product(id); //busines logic
//Only a specific product must have userInputText <= 10 characters.
//Other products may have as many characters as the user wants.
if(product == Enum.SpecificProduct && userInputText.Count() > 10)
{
//The user input text comes from the View...
//If it has more then 10 characters, need to send the errorMessage to the View.
return Json(new { success = false, errorMessage = "error message" }, JsonRequestBehavior.AllowGet);
}
//Otherwise, do stuff on the product...
//and return success at the end.
return Json(new { success = true });
}
On the other hand, on the client-side I have this:
using (Ajax.BeginForm("DoStuff", ajaxOptions))
{
<span>Enter the text:</span>
#Html.TextArea("userInputText", new { onkeyup = "SyncContents(); return false;" })
<input type="submit" value="Add" />
<!-- error message should be displayed here-->
}
This is the AjaxOptions:
var ajaxOptions= new AjaxOptions
{
OnSuccess = "reload",
OnFailure = "FailMessage"
};
If the entered text have more then 10 characters, when the "Add" button is pressed, the Controller is being executing the code on the server-side and fails, how can I get the errorMessage from there and use it here, in the View, to inform the user ?
I tried to alert a message:
<script>
function FailMessage() {
alert("Fail Post");
}
</script>
But no pop-up "Fail post" appears.
Best regards.
The problem here is the Ajax helper thinks all your responses are successful. Your controller action is returning HTTP 200 so there isn't a problem.
https://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxoptions.onfailure(v=vs.118).aspx#P:System.Web.Mvc.Ajax.AjaxOptions.OnFailure
AjaxOptions.OnFailure Property
This function is called if the response status is not in the 200 range.
So you'll need to use the success handler and explicitly check the JSON success parameter.
Or have your action change the HttpStatusCode for the response.
if (notValid)
{
Response.StatusCode = 400; // Bad Request
return Json(new { success = false, errorMessage = "error message" }, JsonRequestBehavior.AllowGet);
}
But for a validation error here I'd just check the for an error in the success handler.
And yes, you should validate on the client and on the server.
I'm trying to make a client-server application where from the client I send a request through a JSON object to the server to register. The thing is I should get another JSON with an "OK" field (which is actually being sent) but for some reason the client keeps going to the .fail function instead of the .done one (sorry if some of used terms are not very accurate, I'm new to this).
So I'll this is my code incase you can check if there's anything wrong causing this:
Client JS:
define(['ojs/ojcore', 'knockout', 'jquery', 'appController', 'jquery', 'ojs/ojknockout', 'ojs/ojinputtext'],
function(oj, ko, $, app) {
function RegistrarseViewModel() {
var self = this;
this.email = ko.observable();
this.pwd1 = ko.observable();
this.pwd2 = ko.observable();
this.registrar = function(){
alert("Se ha mandado el registro");
var p = {tipo:"Registrarse",email: this.email(), pwd1:this.pwd1(), pwd2:this.pwd2()};
$.ajax({
type:"POST",
url:"http://localhost:8080/ServidorWeb/Registrarse.jsp",
data: "p=" + JSON.stringify(p)
}).done(function(data, textStatus, jqXHR){
alert("Comprobando tipo");
if (data.tipo == "OK"){
//window.location="index.html?root=juegos"
sessionStorage.jugador=self.email();
app.router.go("login");
alert("Registro correcto");
}else
alert(respuesta.texto)
}).fail(function() {
alert("Sorry. Server unavailable. lol ");
});
}
this.cancelar = function(){
app.router.go("login");
}
}
return new RegistrarseViewModel();
}
);
Server JSP:
<%# page language="java" contentType="application/json ; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# page import= "org.json.*,dominio.Manager"%>
<%
String p = request.getParameter("p");
JSONObject resultado=new JSONObject();
try{
JSONObject jso= new JSONObject(p);
if(!jso.getString("tipo").equals("Registrarse")){
resultado.put("tipo","NOK");
resultado.put("texto","Mensaje inesperado");
}else{
String email=jso.getString("email");
String pwd1=jso.getString("pwd1");
String pwd2=jso.getString("pwd2");
Manager.get().registrarse(email,pwd1,pwd2);
resultado.put("tipo","OK");
resultado.put("texto","Te has registrado con el email " + email);
}
}
catch(Exception e){
resultado.put("tipo","NOK");
resultado.put("texto","Mensaje Inesperadoo");
}
%>
<%=resultado.toString()%>
After executing Manager.get().registrarse(email,pwd1,pwd2); (which is the logic to register into a MongoDB) it just continues with the resultado.put("tipo","OK"); line which means the problem isn't in there.
Also if I send the request http://localhost:8080/ServidorWeb/Registrarse.jsp?p=%7Btipo:%22Registrarse%22,email:%2233%22,pwd1:%2220%22,pwd2:%2220%22%7D from a browser like Google Chrome it prints this: {"texto":"Te has registrado con el email 33","tipo":"OK"} but from the real client it just won't get into the .done function, idk why.
I really hope you can help me.
Thanks in advance.
EDIT 1: Added the server response from the browser console IMAGE
Okay I solved this finally.
I had to add this line at the beggining of the .jsp, this was an issu with TomCat which has something like 2 machines and without this line it doesn't allow communication among different machines because of security reasons it seems.
response.setHeader("Access-Control-Allow-Origin", "*");
if you use jquery the correct way is use serialize function from jquery
https://api.jquery.com/serialize/
first give a id for you form something like :
`
$("#myform form").submit(function(event){
event.preventDefault();
var sendData = $("#myform form").serialize();
$.post("your-PHP-handler.php", sendData);
});
<form id="myform" method="post" action="your-PHP-handler.php">
<input type="name" placeholder="name">
<input type="name" placeholder="age">
<input type="name" placeholder="address">
<button type="submit">send</button>
</form>
`
note when you submit your form via javascript the serialization jquery get all inputs in your post end send all together you cam handler the response php inside of $.post() you can make many things with this consulting jquery documentation.
anyway the basic is there , get everything inside my form and send to my php file