Asp.net returning whole page - javascript

I've been trying to develop a site which has a login system.
As part of that I want to make an AJAX call to the server to handle the login system with the username and password.
When I make the call, it goes through well but i recieve the entire web page in return and I don't know why
Ajax call(JS):
function AJAXfunc(username, password) {
var parameter = JSON.stringify({ "username": username, "password": password })
$.ajax({
type: "POST",
contentType: 'application/json; charset=utf-8',
url: '/Login?handler=LoginFunc',
data: parameter,
dataType: 'json',
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
success: function (data) {
onsuccess(data)
},
error: function (data, success, error) {
alert("Error: " + error + " - " + data + " - " + success + " - " + data.value)
}
})
}
Server side code(C#):
public class LoginModel : PageModel
{
public async Task<IActionResult> OnPostLoginFuncAsync(HttpContext http, JsonDocument json)
{
return new JsonResult("success");
}
}
Any help would be much appreciated
Thanks
Edit: here is the code that calls the ajax function
function onLoginLoad() {
const formLogin = document.getElementById("login");
formLogin.addEventListener("submit", function (event) {
const userName = formLogin.getElementsByClassName("username")[0].value;
const password = formLogin.getElementsByClassName("password")[0].value;
// stop form submission
event.preventDefault();
AJAXfunc(userName,password);
});
}
here is the HTML code
<form id = "login" action = "/LoginFunc" method = "post">
<h1>Login</h1>
<small></small>
<div class = "field">
<label for = "username" class="loginpg" style="top:45%;left:45%;position:fixed;color:white; width:10%;">Username</label>
<input type="text" class="username" name="username" id="username" style="top:48%;left:45%;position:fixed;width:10%;" placeholder = "Username"><br><br>
</div>
<div class = "field">
<label for = "password" class="loginpg" style="top:51%;left:45%;position:fixed;color:white;width:10%;">Password</label>
<input type= "password" class="password" id="password" name="password"style="top:54%;left:45%;position:fixed;width:10%;" placeholder = "Password"><br><br>
</div>
<input type="submit" value="Submit" class = "loginpg" style="top:57%;left:45%;position:fixed;width:10%;">
</form>
This is the exact error: 'Unexpected token '<', "\r\n\r\n<!DOCTYPE "... is not valid JSON'

yes, as a general rule if you client side js code is a big pile of a mess?
Then hitting the web page will OFTEN just choke, and simple return the whole page. When this occurs, it means your code is all wrong.
When you build/make a ajax call, you can pass values in the URL. This is what we call a REST call.
However, in most cases, we all "very much dislike" having to use those messy URL parmaters, so when we use .ajax calls, we perfer to use the .data option of the jQuery .ajax call.
Your code looks to have BOTH - and that's not going to work.
next up:
Remember those .ajax calls are NOT a post-back, and that means in code behind for that page class, such code does NOT have use of an "instance" of the page class (that code for example can't see/use/enjoy/change controls on the page).
So, that "method" of the page class MUST be static - since no "instance" of the page class will exist (since there is no page post-back).
So, dump the parmtaers in the URL - use ONE or the other (data, or URL based parmaters).
next up, if you NOT createing a seperatet asmx page with page methods, then if you choose to place the web methods in the existing page? (and I much like this choice, since then code and web methods are in the same place?
Then that web method must be MARKED as a web method, and also must be a static member of that page.
So, your code would/should look like this:
So, say client side markup and js code:
<h3>Enter user</h3>
<asp:TextBox ID="txtUser" runat="server" ClientIDMode="Static">
</asp:TextBox>
<h3>Enter password</h3>
<asp:TextBox ID="txtPass" runat="server" ClientIDMode="Static">
</asp:TextBox>
<br />
<asp:Button ID="cmdLogIn" runat="server" Text="Login"
OnClientClick="mylogin();return false;"
/>
<script>
function mylogin() {
sUser = $('#txtUser').val()
sPass = $('#txtPass').val()
AJAXfunc(sUser,sPass)
}
function AJAXfunc(username, password) {
var parameter = JSON.stringify({ "username": username, "password": password })
$.ajax({
type: "POST",
contentType: 'application/json; charset=utf-8',
url: 'WebCalltest.aspx/LoginFunc',
data: parameter,
dataType: 'json',
success: function (mydatastuff) {
alert('return value = ' + mydatastuff.d)
// onsuccess(mydatastuff.d)
},
error: function (data, success, error) {
alert("Error: " + error + " - " + data + " - " + success + " - " + data.value)
}
})
}
</script>
And code behind (assuming same page), then is this:
[WebMethod]
public static string LoginFunc(string username, string password)
{
// do whatever
return "this is the string return result";
}
So, now when we run above, we get/see this:
So, above is the "basic" layout and "pattern" as to how this works.
Now in above example, the web method in the page is on/placed in the same page - hence the URL change I used in above. You of course will have to change the url to your current page. And be careful, the page URL is relative to your current page - the "/" does not mean root in js code.
Also note close, the return value is a .d attribute. This is a .net quirk, and thus you don't use data, but use data.d, or in my example mydatastuff.d
So, don't forget/leave out the .d to get the return result from that web method.

Related

Issue with my Ajax & JQuery using Spring MVC in java

My jQuery AJAX implementation does not work properly, so if i want add, delete, update a product, or retrieve all sites, it simply does not react to my clicks.
Here is my simple web-page that allows me to click but i donot get any result.
When someone wants to submit the form with the specified ID, all form fields are assigned to appropriate variables. After that, a new JSON document is generated based on the form field variables. Then the AJAX call is performed. It is directed to URL which is specified in the action attribute of form tag. The JSON is used as a data which needs to be processed.
You can downlaod my project from here
I get there errors:
localhost:8080/api/sites Failed to load resource: net::ERR_CONNECTION_REFUSED
2localhost:8080/api/sites/ Failed to load resource: net::ERR_CONNECTION_REFUSED
From my Java class:
#RequestMapping(method = RequestMethod.GET, value = "/api/sites")
public List<Site> getAllSites(){
return siteService.getAllSites();
}
#RequestMapping(method = RequestMethod.POST, value = "/api/sites")
public void addSite(#RequestBody Site site){
siteService.addSite(site);
}
A webpage to replicate the problem:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<hr><p> New page </p>
<input name="search" type="text" maxlength="100" id="search"/>
<button onclick="getAllSites()"> Show All </button>
<hr>
<hr>
<p> Id: <input name="search" type="text" maxlength="100" id="id"/></p>
<p> First name: <input name="search" type="text" maxlength="100" id="name"/></p>
<button onclick="addSite()"> Save </button>
<div id="site"></div>
<script>
function addSite()
{ var data = {
id: document.getElementById("id").value,
name: document.getElementById("name").value
}
$.ajax({
url: "http://localhost:8080/api/sites",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: "POST",
dataType: "json",
data: JSON.stringify(data)
});
}
function getAllSites()
{
$("#site").html("");
$.getJSON("http://localhost:8080/api/sites/", function(data)
{
for (var i in data) {
$('#site').append("<p>ID: " + data[i].id + "</p>")
$('#site').append("<p>Name: " + data[i].name + "</p>")
}
});
}
</script>
</body>
</html>
Assuming that the ajax implementation is in a file for example: mySites.html and you need to test it directly from browser or from other site try this:
Go to SiteController.class
If you need to test your api outside of your localhost:8080 then add #CrossOrigin annotation to the specific method of SiteController.class, for example in this case I'm enabling CrossOrigin for two specific methods:
Method 1
#CrossOrigin(origins = "*")
#RequestMapping(method = RequestMethod.GET, value = "/api/sites")
public List<Site> getAllSites(){
return siteService.getAllSites();
}
Method 2
#CrossOrigin(origins = "*")
#RequestMapping(method = RequestMethod.POST, value = "/api/sites")
public void addSite(#RequestBody Site site){
siteService.addSite(site);
}
For more information about #CrossOrigin see the following documentation from spring site #CrossOrigin Document
My conclusion of this answer is because the first time that I ran the ajax implementation I got the No 'Access-Control-Allow-Origin' header exception from console developer, wich means that for security reasons the browser block the ajax request when it is outside of the rest api host.
All the rest of the components (backend java classes, spring) worked perfect after I get imported to my development environment.

invisible recaptcha with knockout js

I am getting the invisible recaptcha done, but I am having a problem implementing it, the code in the developers page in google show it should be like this
<button
class="g-recaptcha"
data-sitekey="6Lee9CEUAA....."
data-callback="YourOnSubmitFn">
Submit
</button>
But the button on my page is currently includes knockout js data binding which I use to call the login function which sends the ajax call to the back end, but if I use the googles given code, I am not sure how to call the functions in my knockout js file.
Here is the old codes.
<button type="submit" class="btn btnlogin" data-bind="disable: (loggedIn() == 'true'), click: callLoginFunction">
SIGN IN
</button>
And here is the knockout js function.
self.callLoginFunction= function () {
self.getRecaptchaCode();
$.ajax({
type: 'POST',
url: BASEURL + 'index.php/login/loginUsingAjax/' + auth,
contentType: 'application/json; charset=utf-8',
data: ko.toJSON({
email : self.eMail(),
password : self.passWord(),
recaptcha : self.recaptchaCode()
})
})
.done(function(returnmsg) {
return window.location.href = BASEURL + 'index.php/main/index';
})
.fail(function(jqXHR, textStatus, errorThrown) {
self.loggedIn('failed');
grecaptcha.reset();
})
.always(function(data){
self.passWord(null);
});
};
So I would like to know how can I call this function using the new codes given by google, I tried removing data-callback and adding data-bind but dint work so need help.
The comment by Jose Luis was headed down the right path! And George Dimitriadis was thinking the right way, if you combine what they suggest you have a solution.
By following that link you learn that you can easily set up a jquery function to call a knockout function. Then you could set your button up to send that Jquery function as the callback function, which will just call your knockout function, which will send the grecaptcha response as part of its ajax request.
So in your head tag perhaps create a jquery function like this:
<script>
function loginCB() {
yourViewModel.callLoginFunction();
}
</script>
yourViewModel would be what you named your instance of your view model, for example:
<script>
yourViewModel = new login_vm();
ko.applyBindings(yourViewModel, $("#login")[0]);
</script>
Now create your button like google suggests sending that new Jquery function as the callback function:
<button
class="g-recaptcha"
data-sitekey="6Lee9CEUAA....."
data-callback="loginCB">
Submit
</button>
I had success getting the recaptcha response code by using grecaptcha.getResponse(), so I would alter your knockout callLoginFunction like this:
self.callLoginFunction= function () {
response = grecaptcha.getResponse()
$.ajax({
type: 'POST',
url: BASEURL + 'index.php/login/loginUsingAjax/' + auth,
contentType: 'application/json; charset=utf-8',
data: ko.toJSON({
email : self.eMail(),
password : self.passWord(),
recaptcha : response
})
})
.done(function(returnmsg) {
return window.location.href = BASEURL + 'index.php/main/index';
})
.fail(function(jqXHR, textStatus, errorThrown) {
self.loggedIn('failed');
grecaptcha.reset();
})
.always(function(data){
self.passWord(null);
});
};
The way you were getting the response code to send with your ajax request might have been fine, I just couldn't see how you did it.
I assume you were asking how to set up the client side of the recaptcha, so I will assume you know what to do with that response code you are sending with your ajax request on your server.

How to add Header Authorization for POST FORM using JS/AJAX/JQUERY?

I wanna get inputs using a form on my page and submit those values to a php hosted on another external site. Request maker extension shows the Header Authorization being passed along with other inputs when submitting data on the external site.
The result is probably an xml file (Student Record).Need to pull and show it as result.
Tried a lot using $.Ajax and jquery in vain. Please help.
[1]: http://i.stack.imgur.com/rDO6Z. jpg
[2]: http://i.stack.imgur.com/92uTh. jpg
function myFunction() {
var name = document.getElementById("name").value;
// AJAX code to submit form.
$.ajax({
type: "POST",
url: "http://externalsite.cpm/results.php.php",
data: dataString,
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', "Basic XXXXXXXXXXXXXXXXXXXXXXXXX" ); or xhr.setRequestHeader('Authorization', "Basic " +btoa(ser_user + ':' + ser_pass));
},
cache: false,
success: ???
xmlhttp.open("POST","your_url.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("name=" + name + "&email=" + email);
<body>
<form action="http://externalsite.cpm/results.php" method="post" >
Enter Your Name<br>
<input type="text" name="name" >
<br>
<input type="submit" onclick="myFunction()" value="Submit">
</body>
How do I add this header authorization when submitting values from my page to external php? Please Help !
Its bit late but still posting the answer for future readers who might face the same issue.
Please do not provide the form submit url (action) and method type (POST) inside the html code when it is explicitly mentioned inside the ajax request.
Notice the corresponding changes added in the code snippets given.
Html form code :
<form><!---Removed form submit url-->
<input type="text" id="keyName" value="testValue">
<!---Id attribute added to input field to be submitted--->
<input type="button" onclick="myFunction()" value="Submit">
<!---Input type is button NOT submit--->
</form>
Javascript code:
function myFunction(){
var dataValue = $("#keyName").val();
$.ajax({
type : 'POST',
//remove the .php from results.php.php
url : "http://externalsite.cpm/results.php",
//Add the request header
headers : {
Authorization : 'Bearer ' + 'XXXXXXXXXXXXXXXXXXXXXXXXX'
},
contentType : 'application/x-www-form-urlencoded',
//Add form data
data : {keyName : dataValue},
success : function(response) {
console.log(response);
},
error : function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
console.log(err);
}
}); //End of Ajax
} // End of myFucntion
Update :
PHP service results.php
<?php
print_r($_POST["keyName"]);
?>
I had a similar issue, needed to add authentication header name and authentication token value in the HTTP POST request headers. Added this javascript interceptor function in one of the JSPs that forms the HTML panel that's part of every page in the web application.
// this will add employee authentication headers to every ajax call
(function() {
var site = window.XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function() {
this.setRequestHeader("${employee.role.header}", "${employee.auth.secret}")
return site.apply(this, [].slice.call(arguments));
};
})();

I usually wait for a collection of asynchronous events to finish using a setInterval poller. Is there a better way? [duplicate]

Let me explain my code a little bit (Excuse me if somethings wrong, I've just written this example from scratch, it is very close to what I currently have).
HTML:
<form id="form">
<!-- Friend 1 -->
Name 1: <input type="text" name="friendName1" id="friendName1" class="friendName" value=""><br />
Email 1: <input type="text" name="friendEmail1" id="friendEmail1" value=""><br /><br />
<!-- Friend 2 -->
Name 2:<input type="text" name="friendName2" id="friendName2" class="friendName" value=""><br />
Email 2:<input type="text" name="friendEmail2" id="friendEmail2" value=""><br /><br />
<!-- Friend 3 -->
Name 3:<input type="text" name="friendName3" id="friendName3" class="friendName" value=""><br />
Email 3:<input type="text" name="friendEmail3" id="friendEmail3" value=""><br /><br />
<!-- Friend 4 -->
Name 4:<input type="text" name="friendName4" id="friendName4" class="friendName" value=""><br />
Email 4:<input type="text" name="friendEmail4" id="friendEmail4" value=""><br /><br />
<!-- Submit -->
<input name="submit" type="submit" value="Submit">
</form>
JS:
$("#form").submit(function(){
$(".friendName[value!='']").each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
if($("#"+idEmail+"[value!='']").length > 0){
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
});
}
});
// Redirect the user to the thank you page
setTimeout( function() { window.location= '/thanks'; }, 2000 );
});
JSFiddle (redirect removed and ajax call replaced with console log for fiddle)
http://jsfiddle.net/cM5PX/
The HTML is a simple form, with friend name and friend email input fields.
The JS has an each function, which if the name and associated email have values, it runs an ajax call.
I need a way for these ajax calls to run (there could be 1 loop, there could be 15) and then after they have all finished, redirect to a new page.
The current way I'm doing it is horrible, as all of the ajax calls do not finish running before the page redirects.
What can I do to make this better? It needs to be fool proof and ONLY redirect once all of the ajax calls have finished (success or error, it doesn't matter - it just needs to redirect once its finished).
I have tried using async: false but it doesn't seem to make a difference.
I've thought about putting a counter in the each function and a counter in the ajax success function and if they both match, then do the redirect, but I am looking for some more experienced guidance.
Use deferred objects:
$("#form").submit(function(e){
e.preventDefault();
var calls = [];
$(".friendName[value!='']").each(function(){
// Submit the ajax request
calls.push($.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
}));
});
$.when.apply($, calls).then(function() {
window.location= '/thanks';
});
});
Ok, this is fairly easy since you're using jQuery. jQuery comes with an integrated promise maker which also is wired up with jQuery's Ajax calls. What does that mean? Well, we can easily go like this:
var requests = [ ];
// ...
// Submit the ajax request
requests.push($.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
}));
// at this point we filled our array with jXHR objects which also inherit the promise API
$.when.apply( null, requests ).done(function() {
document.location.href = '/thanks';
});
Note: The above code will only fire, if all requests completed successfully. If you need to handle the case if one ore more requested failed, use .then() or .fail() instead of .done(), too.
Just keep a counter of the AJAX calls and check to see when they have all completed.
Something like this:
$("#form").submit(function(){
var ajaxMax = $(".friendName[value!='']").length, ajaxCounter = 0;
$(".friendName[value!='']").each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
if($("#"+idEmail+"[value!='']").length > 0){
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
if(++ajaxCounter >= ajaxMax)
window.location= '/thanks';
}
});
}
});
});
By default $.ajax is asynchronous. In the options hash being passed, add
async: false
That will serialize the calls you are making having it perform the way you want.
After getting comment from original poster, possible solution may be to do the following:
Inside the submit call determine the number of calls that should be made.
Store this result as a local variable within the handler function
Create a callback on 'complete:' that will examine the value of the calls
If the number of calls to be made is greater than 0, then decrement the value and return
If the number of calls reaches zero, update the window.location (really should use window.location.href as window.location is an object but browsers will allow this and perform correctly)
Note, I don't have any information on the thread safety of performing this kind of operation so YMMV.
Example Code:
$("#form").submit(function(eventObject){
var $ajaxFields= $(".friendName[value!='']").filter(function(index){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
return ($("#"+idEmail+"[value!='']").length > 0);
});
var numberToSubmit= $ajaxFields.length;
$ajaxFields.each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("call not completed: "+textStatus);
},
complete: function(jqXHR, textStatus) {
if( --numberToSubmit == 0 ) {
window.location.href= '/thanks';
}
}
});
});
// Prevent default form submission
return false;
});

Send data with jquery to an MVC controller

I have an ASP.NET MVC3 app and when the user clicks on my anchor tag, I want to send 3 pieces of data to an action:
<a onclick='editDescription(<#= DocID,FileName,Description #>)'></a>
This is the javascript to call my action:
function editDescription(docId,fileName,description) {
var url = "#Url.Content("~/OrderDetail/_EditDescription/")" + docId+'/'+
fileName + '/' + description;
//do the rest}
My action:
public ActionResult _EditDescription(string id,string filename, string descritpion)
The pieces im concerned about are FileName and Description because these can be loooooong and i dont want a url to appear like so:
http://localhost/OrderDetail/_EditDescription/123/some long filename.pdf/this is a long description for the name
How can i send across my data to my action without having to send it like a query string? Thanks
You can use the jQuery $.ajax method:
<div id="what-I-want-updated">
<input id="whatever-the-id-is" type="text" value="#Model.ID" />
<br />
<input id="whatever-the-filename" type="text" value="#Model.Filename" />
<br />
<input id="whatever-the-description" type="text" value="#Model.Description" />
<br />
<button id="whatIsClicked">Update!</button>
</div> <!-- /#what-I-want-updated -->
<script>
// You're probably clicking something to initiate update
var $whatIsClicked = $('#whatIsClicked');
// .live persists on the page even after other ajax calls
// So when the thing is clicked
$whatIsClicked.live('click', function() {
// Grab the information needed to update
var theId = $('#whatever-the-id-is').val(); //Or it could be .text()
var theFilename = $('#whatever-the-filename').val();
var theDescript = $('#whatever-the-description').val();
// Let's edit the description!
$.ajax({
type: "POST",
url: "OrderDetail/_EditDescription", // the method we are calling
contentType: "application/json; charset=utf-8",
data: {id: theId, filename: theFilename, description: theDescript},
dataType: "json",
success: function (result) {
alert('Yay! It worked!');
// Or if you are returning something
alert('I returned... ' + result.WhateverIsReturning);
},
error: function (result) {
alert('Oh no :(');
}
});
});
</script>
Even though it will still work, make sure you change your Controller method to:
[HttpPost]
public ActionResult _EditDescription(string id, string filename, string descritpion)
You can do a full post of the form if you like either through ajax $.post or by having an action with [HttpPost] attribute.
Declare your action as a POST
[HttpPost]
public ActionResult _EditDescription(string docId, string filename, string description)
Create an invisible HTML form:
<form action="#Url.Content("~/OrderDetail/_EditDescription/")" method="post" name="editDescriptionForm">
<input type="hidden" name="docId" />
<input type="hidden" name="fileName" />
<input type="hidden" name="description" />
</form>
Fill out the form and submit it with JS:
function editDescription(docId, fileName, description) {
document.editDescriptionForm.docId = docId;
...
document.editDescriptionForm.submit();
}

Categories