How to ajax post to a razor page handler? - javascript

The code looks like this
HTML:
<form class="col-sm-6" name="log" >
<div class="form-group row">
<label class="col-sm-3 col-form-label"></label>
<div class="col-sm-7">
<input name='logText' class="form-control">
</div>
</div>
<div class="form-group row">
<div class="col-sm-7 offset-sm-3">
<button class="btn btn-primary" id="submit">Submit</button>
</div>
</div>
</form>
Javascript:
document.forms['log'].onsubmit = () => {
let formData = new FormData(document.forms['log']);
fetch('?handler=log', {
method: 'post',
body: new URLSearchParams(formData)
})
.then(() => {
alert('Posted using Fetch');
});
return false;
};
</script>
C#:
public void OnPostLog(string logText)
{
}
The ajax post goes through with a request that looks like this
Request URL: https://localhost:44345/?handler=log
Request Method: POST
Status Code: 400
Remote Address: [::1]:44345
Referrer Policy: no-referrer-when-downgrade
However the server returns a 400. An ajax get works fine. A full page post to the handler works fine. Just not an ajax post to a handler. Is this capability even supported in Razor Pages?

The reason is, there is a __RequestVerificationToken embedded into the form. and this needs to be supplied during the ajax post. But for the token to be added to the form, you have to add method="post" the below to the form.
<form class="col-sm-6" name="log" method="post" >
Source: https://www.talkingdotnet.com/handle-ajax-requests-in-asp-net-core-razor-pages/

Whenever I use fetch API, I use the FormData object as the body for the request instead of creating a new URLSearchParams object.
Hope it helps.

Related

Angularjs ensuring the json posted data has been transmitted

I am trying to send data from a Angularjs app to php in order to insert it into mysql db .
I have the index.html that contains the script,getUser_api.php page and insert.php page
I hav not error in console but I failed insert into mysql db.
So Is there any way to ensure if json data has been transmitted or nor
var app = angular.module("app",['ui.router']);
app.controller("insertCtrl", function($scope,$rootScope, $http) {
$scope.insert = function() {
$http.post(
"getUser_api.php", {
'Customer_Name': $scope.Customer_Name,
'Cust_mail': $scope.Cust_mail,
'Cust_Address': $scope.Cust_Address
}) ;
}
});
My insert.php page
<div class="well col-xs-8 col-xs-offset-2" style="margin-top: 10%" ng-controller="insertCtrl">
<form>
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" ng-model="Customer_Name">
</div>
<div class="form-group">
<label> mail</label>
<input type="text" class="form-control" ng-model="Cust_mail">
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" ng-model="Cust_Address">
</div>
</form>
<button class="btn-block btn-info" ng-click="insert()">Insert</button>
</div>
getUser_api
<?php
include('config.php');
$result=mysql_query('select * from customers');
$data['results']=array();
while($row=mysql_fetch_assoc($result)){
array_push($data['results'],$row);
}
if(count($data['results'])>0)
$data['status']='OK';
else
$data['status']='Z-Result';
echo json_encode($data);
?>
If you want to check manually, you can check it in the browser - developer tools in XHR tab.
In case if you want to catch error in the js end you can do:
var dataToSend = {
'Customer_Name': $scope.Customer_Name,
'Cust_mail': $scope.Cust_mail,
'Cust_Address': $scope.Cust_Address
};
var req = {
method: 'POST',
url: 'getUser_api.php',
data: JSON.parse(JSON.stringify(dataToSend))
};
$http(req).then(function (response) {
//handle success
}, function (error) {
//handle error
});
How to check manually in browser:
Open Chrome and press F12 for developer options
Click on Network
Click on XHR
Now in your html page click on the button which will call your inser method.
Your request will be displayed like following
Click on the request sent
Click headers
You will be able to see your Json in Request payload

Mithril ajax sending empty inputs

I'm trying to send a POST request through ajax and Mithril.js using CodeIgniter. But for some reason the input always is empty. I have tried with a regular ajax post request and that works fine, but Mithril doesn't.
m.request({
method: "POST",
url: "http://localhost/index.php/login",
data: {
username: $("#login-username").val(),
password: $("#login-password").val()
}
})
.then(function(result) {
console.log(result)
})
And the php
public function login()
{
$username = $this->input->post('username');
die($username);
}
It always prints "null" in console. Any ideas?
UPDATE:
<form class="uk-form-stacked uk-margin-remove" id="login-form" method="post" action="index.php/login">
<fieldset class="uk-fieldset">
<div class="uk-margin">
<div class="uk-inline uk-width-1-1">
<span class="uk-form-icon" uk-icon="icon: user"></span>
<input class="uk-input" id="login-username" name="username" type="text" placeholder="Username">
</div>
</div>
<div class="uk-margin">
<div class="uk-inline uk-width-1-1">
<span class="uk-form-icon" uk-icon="icon: lock"></span>
<input class="uk-input" id="login-password" name="password" type="password" placeholder="Password">
</div>
</div>
<div class="uk-margin" style="margin-top:10px">
<label ><input class="uk-checkbox" type="checkbox"> Remember me</label>
</div>
<input type="submit" class="uk-button uk-button-primary uk-width-1-1" value="Login">
</fieldset>
</form>
Routes:
$route['login']['post'] = 'Users/login';
That code will send a JSON body to the server, not a form submission. I'm guessing your PHP code expects the data to be formatted like a <form> would send it, so for that you'd want to use a FormData instance.
var data = new FormData();
data.append("username", document.querySelector("#username").value);
data.append("password", document.querySelector("#password").value);
m.request({
method: "POST",
url: "https://httpbin.org/post",
data: data
})
.then(function(result) {
console.log(result)
})
I also set up a JsBin where you can see this working & poke at it.
https://jsbin.com/gififo/2/
try print the data to be able to see it i the console .
public function login()
{
$username = $this->input->post('username');
echo $username;
}
I don't know if you have define a route (in app/config/route.php) but, actually you are pointing to the default controller.
If you are trying to send your request to, for exemple, the login method of the users controller, your request path should be http://localhost/index.php/users/login
I also recommand you to use the base_url function instead of a simple string, which is far more easier when you deploy your app on the real server.
So, I propose to change this line
url: "http://localhost/index.php/users/login",
By
url: <?= json_encode(base_url("/users/login")) ?>,
For this function work, you should have load the URI helper, in your controller __construct or directly in your current method :
$this->load->helper('URI');

$http not working in Angularjs 1.x

I am stuck with angular's all type of $http requests I am trying to hit the rest API with $http but my code ran through it and do not show any call in chrome network tab. I am using python simplehttpserver for my project execution.
Below is the code of the service I am trying to hit
HTML CODE
<form class="form-horizontal" method="post" ng-submit="loginModel.login()">
<div class="form-group">
<div class="col-md-12">
<input type="text" class="form-control" placeholder="Username" ng-model="loginModel.username"/>
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" class="form-control" placeholder="Password" ng-model="loginModel.password"/>
</div>
</div>
<div class="form-group">
<div class="col-md-6">
Forgot your password?
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-info btn-block">Log In</button>
</div>
</div>
</form>
Controller Code
module.exports = function ($scope,$rootScope,$state,crudFactory,$http,$resource) {
var vm = this;
vm.login = login;
function login() {
var userDetail = {
username:vm.username,
password:vm.password
};
$http({
method: 'POST',
url:'http:example.com',
data:userDetail,
}).then(function (response) {
console.log(response)
}, function (response) {
});
}
I have inject $http in my controller and have also tried to hit the API with $resource but nothing is happening when i hit the service on click event.
I have tried this with core javascript and it works fine but why its not working $http or $resouce
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://www.example.com/", false);
xhr.send();
console.log(xhr.status);
Please help me on this
Thanks
It looks like your URL is not formatted correctly, and you aren't doing anything in the event of an error.
$http({
method: 'POST',
url:'http://example.com',
data:userDetail,
}).then(function (response) {
console.log(response)
}, function (response) {
console.log('error response', response);
});
This will at least show something in the console if there is an error.
If the url change still isn't working, check your browser developer console's network tab to see if the request is being made and if so, if it is timing out (stuck in pending state)

Modifying HTML form action with jQuery/Javascript

I am trying to create a post form in HTML using a RESTful express route, something akin to /game/:gameID/node/:nodeRow/:nodeCol/update to update a given node in a given game.
Here's the route code:
app.post("/game/:gameID/node/:nodeRow/:nodeCol/update", function(request, response) {
gameHandler.updateNode(request, response)
});
The reason I'm doing this in HTML is because I haven't created the functionality yet in the actual client (mobile game) so I need something to test it. However, I have not figured out how to make the HTML form so that I can enter the data in the form to replace :gameID, :nodeRow, and :nodeCol without just going to the URL manually, like /game/3/node/2/5/update.
This is a post request and I would like other data to be contained in the form to specify the property to update as well as the new value.
How can I do this, or am I thinking about it wrong?
Edit:
Changed the question title to be more useful.
Try
app.post("/game/:gameID/node/:nodeRow/:nodeCol/update", function(request, response) {
console.log({gameID: request.params.gameID, nodeRow: request.params.nodeRow,nodeCol: request.params.nodeCol, body: request.body});
response.send({gameID: request.params.gameID, nodeRow: request.params.nodeRow,nodeCol: request.params.nodeCol, body: request.body});
});
Sorry I misunderstood your question. I thought you are having difficulties in parsing node parameters in node.
Anyway, there are different ways you can achieve this. Of course you need support of javascript, either pure javascript or jQuery.
Here is an example
<form id="myform">
<input name="gameID" id="gameID" />
<input name="nodeRow" id="nodeRow" />
<input name="nodeCol" id="nodeCol" />
<button name="action" value="bar" onclick="submitForm();">Go</button>
</form>
and javascript (using jQuery) will be
<javascript>
function submitForm(){
$("#myform").attr('action',
'/game/' + $("#gameID").val() + '/node/' + $("#nodeRow").val()
+ '/' + $("nodeCol").val() + '/update');
$("#myform").submit();
}
</javascript>
The way to pass data in a POST request is to push it from the html form controls and retrieve the values from the body of the request. The HTML below defines a form with your variables which you can hand-key from a browser:
<html><body>
<form method="post" action="/game/update" role="form">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">gameID</span>
<input type="text" class="form-control" name="gameID" placeholder="<gameID>" value="123456">
</div>
</div>
<div class="input-group">
<span class="input-group-addon">nodeRow</span>
<input type="text" class="form-control" name="nodeRow" placeholder="<nodeRow>" value="1">
</div>
</div>
<div class="input-group">
<span class="input-group-addon">nodeCol</span>
<input type="text" class="form-control" name="nodeCol" placeholder="<gameID" value="1">
</div>
</div>
<hr>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</body></html>
Then you can write a handler along the lines of what's below. Clicking submit will fire the POST request off, and pulling the variables out of the request body can be done as shown below.
app.post("/game/update", function(request, response) {
updateNodeHandler(request, response)
});
function updateNodeHandler(request, response) {
var nodeID = request.body.nodeID;
var nodeRow = request.body.nodeRow;
var nodeCol = request.body.nodeCol;
// Additional logic goes here...
}

Angular form submitting twice (ajax get request)

I have a controller that for some reason is submitting a form twice via a get request in AngularJs. I can see in my database that the form is being submitted twice, and also in the console network tab, it is logging the two submission, however, the first submission has the "Request Method" of OPTIONS, and the 2nd is GET. I think this may be a clue. I'm a bit confused, because i'm not passing in any 'options' into the get method, just the URL I am submitting to.
Html:
<div class="row">
<div ng-controller="groupEditCtrl">
<form class="span11" name="" novalidate ng-submit="createArtifact()">
<legend>Create a new group</legend>
<div class="row">
<div class="span5">
<div class="control-group">
<div class="controls">
<input name="text" type="text" placeholder="Group Name" required ng-model="artifact.group_name" />
</div>
</div>
</div>
<div class="span5">
<p>
<small>What your artifact will look like:</small><br />
{{artifact.group_name}}
</p>
</div>
</div>
<input name="token" type="hidden" required ng-model="window.token" />
<div class="control-group">
<div class="controls controls-row">
<button type="submit" class="btn" value="Submit" title="Submit">
<span>Submit</span>
</button>
</div>
</div>
</form>
</div>
</div>
Controller:
'use strict';
function groupEditCtrl($scope, $http, $routeParams, $cookie) {
$scope.createArtifact = function(){
var requestURL = window.base_url + "/Group/CreateGroup?callback=JSON_CALLBACK&token=" + window.token + "&group_name=" + $scope.artifact.group_name;
$http.get( requestURL ).
success(function(data, status, headers, config) {
console.log('You have successfully submitted a Cause/CreateCause');
}).
error(function(data,status,headers,config){
console.log('You have FAILED submitting a Cause/CreateCause');
});
}
};
A HTTP Options request is asking the server for the allowed methods that it can communicate with the server upon (amongst other things) so it's a normal thing to happen.
The Options request shouldn't change anything in your backend but it may well be logged as you're seeing. Double check that it isn't changing anything (and if it is then your backend may be configured wrong, and you should ask another question if it is!).
There's nothing wrong with your angular setup/use regarding the OPTIONS then GET.
For me headers: {'Content-Type': undefined} Work, And I don't see it call twice again.
$http.post("index.php", {id : $scope.A},{
headers: {'Content-Type': undefined}})
.success(function (response) {
$scope.OK = response.POLL;
}
}
Turns out this was an issue with the custom api being built that I wasn't aware of.

Categories