Axios and reactjs showing empty posted data at php backend - php

Iam using the Axio Reactjs code below to post form data to php backend.
when I check record.php files from the chrome browser console and
network. it shows that connection is okay but posted data is empty. it seems like the axios is not sending the data to php backend.
I have tried some solutions here on SO but cannot get it to work. Any work around will be appreciated.
axios({
method:'POST',
url:'http://localhost/mydata/record.php',
rec:{
myParameter1: 'test',
myParameter2: 'test2',
}
}).then(res => {
const data = res.data;
this.setState({ data });
console.log(data);
})
.catch(err => { // log request error
//this.setState({ error: false });
console.error(err);
})
php code
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With");
//header("Content-Type: application/json");
//check if file_get_contents is enabled
if( ini_get('allow_url_fopen') ) {
echo "enabled";
} else{
echo "not enabled";
}
$data = file_get_contents("php://input");
$request = json_decode($data);
print_r($request);
print_r($data);
?>

In axios docs you can find data tag:
https://github.com/axios/axios#request-config
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
// When no `transformRequest` is set, must be of one of the following types:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - Browser only: FormData, File, Blob
// - Node only: Stream, Buffer
data: {
firstName: 'Fred'
},
// syntax alternative to send data into the body
// method post
// only the value is sent, not the key
data: 'Country=Brasil&City=Belo Horizonte',
this is what you need, there is no rec property in axios config

Try removing the key rec in your data segment in axios or better still do something along the lines of
{
rec: {
myParameter1: 'test',
myParameter2: 'test2',
}
}

Related

Ionic Angular HTTP POST request to PHP

I'm trying to do a basic POST request from my ionic angular app using the HttpClient from Angular. From that POST, I need to pass the payload to PHP file for me to manipulate another function in the PHP.
I can seem to echo the whole data, but trying to get the single value gives an error.
Below is my code under home.ts
test() {
let data = {
firstname: "John",
lastname: "Wick"
}
const headers = new HttpHeaders();
headers.set('Content-Type', 'application/json; charset=UTF-8');
headers.set('Access-Control-Allow-Origin', '*');
headers.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
this.http.post(this.php_url, data, {headers: headers}).subscribe((res) => {
console.log("Posted successfully")
console.log(res);
}, (err) => {
console.log(err.error);
});
}
In my index.php file, I have the code below.
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: *');
header('Content-Type: application/json');
$json = file_get_contents('php://input');
echo $json->firstname;
?>
I am able to echo $json, but not when trying to get the single value. How do I get the single value from the JSON data?
you have to use
print_r($json['firstname']);
insted of
echo $json->firstname;

PHP api sends HTTP_response_code(400) no matter what

i wrote a Simple PHP crud api and i'm getting HTTP_response_code(400) no matter what i do.
in the api a file named create.php is responsible for inserting new items in the database it checks if the data it receives from ajax isn't empty and then proceeds to creation if it's empty it sends an HTTP_response_code(400).
but, no matter what i do it always sends the HTTP_response_code(400) even though the data is not empty.
i thought the problem was coming from ajax first but after debugging i found out that ajax in facts gets the proper data from the form and sends it.
here is my create.php file
$db = $database->getConnection();
$consumable = new consumable($db);
//get json
$json = file_get_contents("php://input");
// get posted data
$data = json_decode($json);
// make sure data is not empty
if(
!empty($data->reference) &&
!empty($data->price) &&
!empty($data->description) &&
!empty($data->category_id) &&
!empty($data->quantity)
){
// set consumable property values
$consumable->reference = $data->reference;
$consumable->price = $data->price;
$consumable->description = $data->description;
$consumable->category_id = $data->category_id;
$consumable->quantity = $data->quantity;
$consumable->created = date('Y-m-d H:i:s');
// create the consumable
if($consumable->create()){
// set response code - 201 created
http_response_code(201);
// tell the user
echo json_encode(array("message" => "consumable was created."));
}
// if unable to create the consumable, tell the user
else{
// set response code - 503 service unavailable
http_response_code(503);
// tell the user
echo json_encode(array("message" => "Unable to create consumable."));
}
}
else{
// tell the user data is incomplete
// set response code - 400 bad request
//http_response_code(400);
// tell the user
echo json_encode(array("message" => "Unable to create consumable. Data is incomplete."));
echo json_encode($json);
}
and here is my ajax:
$(document).on('submit', '#create-consumable-form', function(){
alert("submit");
// get form data
var form=$(this).serializeObject();
var form_data=JSON.stringify(form);
console.log('a',form);
console.log(form_data);
// submit form data to api
$.ajax({
url: "http://localhost:3000/consumable/create.php",
type : "POST",
contentType : 'application/json',
data : form_data,
success : function(result) {
// consumable was created, go back to consumables list
showconsumables();
},
error: function(xhr, resp, text) {
// show error to console
console.log(xhr, resp, text);
}
});
return false;
});
after filling out the form and submitting instead of adding the entry to the database and sending a 201 OK it shows me the following error:
jquery.js:2 OPTIONS http://localhost:3000/consumable/create.php 400 (Bad Request)
send # jquery.js:2
ajax # jquery.js:2
(anonymous) # create-consumables.js:87
dispatch # jquery.js:2
v.handle # jquery.js:2
index.html:1 Access to XMLHttpRequest at 'http://localhost:3000/consumable/create.php' from origin 'http://localhost:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
and this is the result of my console.log
a {reference: "BT3000", price: "10", quantity: "5", description: "description", category_id: "3"}
create-consumables.js:85 {"reference":"BT3000","price":"10","quantity":"5","description":"description","category_id":"3"}
the weird thing is when i comment the HTTP_response_code(400) line in my create.php file it works perfectly does anyone have any idea of the cause of this behaviour?
Try to put header() in your create.php file:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
json_decode returns null if it cannot decode it. It seems it does just that. Maybe you need to url_decode and/or stripslashes the contents before you can decode it. As Ahmed is saying, try to output the $data variable and the output of the json_decode and file_get_contents("php://input"); and you will see the mistake soon enough.
Also be aware that !empty(0) and !empty(false) returns true. So if your variable has a value which is 0 or false then it will return 400 in this case as well. This is not the issue in your example, but might become an issue later.
the problem was caused by the fact that the content-type in my headers was application/json and i was using postman for testing and i had left it to default content-type which is text

Ionic 4 POST to PHP backend

I'm trying to POST data to a PHP backend and receive back the values and push it into an array. Hence, I created a function to do just that. However, I'm not to change the API on the backend (written in PHP). So I cannot change it to suit my normal methods of using POST.
This is my function
test() {
let data = "method=getThis" + "&db=myDatabase"
this.http.post("API URL", data).subscribe(data => {
this.result = data; // get data in result variable
this.items = JSON.stringify(this.result); // then convert data to json string
// console.log(this.items);
this.allData = JSON.parse(this.items); // parse json data and pass json string
// console.log(this.allData.length); // got result of particular string
this.array = [];
for (var i = 0; i < this.allData.length; i++) {
this.array.push({
data1: this.allData[i].data1,
data2: this.allData[i].data2,
})
}
console.log(this.array[0])
})
}
And this is an example function on the backend
else if($_POST['method']=="getThis"){
global $conn;
mysqli_select_db($conn, $_POST['db']);
$name="";
$result=array();
$r=mysqli_query($conn,"select data1,data2 from table");
while ($rs = mysqli_fetch_array($r,MYSQLI_ASSOC)){
array_push($result,$rs);
}
echo json_encode(array("result"=>$result));
}
So how do I actually get it to post? I'm stuck here. I usually post with JSON and then decode the JSON on the backend. But this time around I'm not developing the backend and not changing it so gotta use the one provided.
Posting using POSTMAN with this
method=getThis&db=myDatabase
works well. Not sending JSON just a text. So how do I actually achieve this in Ionic.
You could try it that way. It works for me:
First import:
import { map } from "rxjs/operators/map";
Your function:
test() {
let data = "method=getThis" + "&db=myDatabase"
this.http.post("API URL", data).pipe(
map(res => res.json())
).subscribe(response => {
//Here your code
// 'response' is json
});
}
Since the data you are sending is in plain text, you will need to add a header mentioning the content type.
import { HttpHeaders } from '#angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'text/html'
})
};
this.http.post("API URL", data, httpOptions).subscribe()
PHP side should be return JSON and told browser content type is application/json, please test your code base on one simple page.
//demo.php
<?php
$data = ['message' => 'Hello world.'];
header("Content-Type: application/json; charset=UTF-8");
//If allow cross domain and not configration in Ngix/Apache
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Accept-Encoding, X-Requested-With, Content-Type, Origin, Accept, Authenticationtoken");
echo json_encode($data);
And please try http access demo.php again.

Unwanted "data" wrapper in PHP response to AngularJS query

I am querying some server with AngularJS using $http.get
var onStuff = function(data) {
console.log( "Stuff received: " + angular.toJson(data));
$scope.stuff = data.data;
};
$http.get("https://some.server.net/stuff")
.then(onStuff, onError);
My back end is written in php and returns a properly formatted JSON.
I checked that loading https://some.server.net/stuff in a browser and testing by command line "php stuff.php" . It looks something like (truncated with ... to fit this screen):
[{"id":"1","user_id":"1","name":"Name1"},
{"id":"2","user_id":"1","name":"Name2"},
...
]
Please note this data is "unwrapped" or "just the array"
However, when onStuff() is invoked my array is "wrapped" inside another data object
Here is the console output
Stuff received:
{"data":[{"id":"1","user_id":"1","name":"Name1"},
{"id":"2","user_id":"1","name":"Name2"},...],
"status":200,
"config":{"method":"GET",
"transformRequest":[null],
"transformResponse":[null],
"url":"https://some.server.net/stuff",
"headers":{"Accept":"application/json, text/plain, */*"}},
"statusText":"OK"}
Here is the php stuff
<?
header('content-type: application/json; charset=utf-8');
header("access-control-allow-origin: *");
require_once("stuff.class.php");
$mysqli = new mysqli( "localhost", "user", "password", "database");
$list = Stuff::getList( $mysqli);
echo json_encode( $list);
$mysqli->close();
?>
I have been following a tutorial using github api, the JSON response was available directly in data
I am pretty sure this has to do with HTTP headers, but I hoped content-type would take care of it
What should I do to remove the unwanted "data" wrapper?
Instead of using the generic promise API (which seems to return an object with everything inside), use the success and error methods provided by $http:
var onStuff = function(data) {
console.log( "Stuff received: " + angular.toJson(data));
$scope.stuff = data.data;
};
$http.get("https://some.server.net/stuff")
.success(onStuff).error(onError);
That should gives you the data in the format you expect. The full API is as follow:
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
It seems like you expect onStuff to receive only the deserialized JSON data, but that's not what the API does. The object passed to your $http.get(...).then() callback (i.e. onStuff) is a response object with five properties: data, status, headers, config, and statusText--which is exactly what you're seeing in your console output. The data property has the deserialized JSON data, which is why you have to do $scope.stuff = data.data.
If you want onStuff to receive only the deserialized JSON data, you'll have to call it through an intermediary:
$http.get("https://example.com/stuff")
.then( function(response) {
onStuff(response.data);
} );

Jquery Callback Was Not Called

I've Googled every instance of this error I can find, and none of the solutions work for me. In essence, I am doing what others have suggested. Despite that, I am receiving an error that my callback function is not being called. I am using Ajax/Jquery/JASONP to do a cross domain form submission using GET. Here is my code on the form side:
$(document).ready(function() {
$("#ajaxform1").submit(function(e){
e.preventDefault();
var surl = "http://blahblah/test_create_user.php?callback=?";
$.ajax({
type: 'GET',
url: surl,
crossDomain: true,
data: $('#ajaxform1').serialize(),
dataType: "jsonp",
success: function(msg) {
$.each(msg, function (index, value) {
if(value==1)
{
alert("New User Added");
} else {
alert("User Already Exists")
} }
});
},
error: function(xhr, status, error) {
var myerror = xhr+" "+status+" "+error;
alert("Failure Connecting to Kayako. Please Try Again("+myerror+")"); }
});
Here is the applicable snippet of my PHP Code:
if($USER_CHK->first()->id){
$data = array('msg' => '0'); // user exists
else {
$data = array('msg' => '1'); // User added
}
//echo customerAdded(FALSE);
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization,X- Requested- With');
header("Content-type: application/json");
$data = array('msg' => '0');
print $_REQUEST['callback']. '('.json_encode($data).')';
exit;
});
});
My debugging shows that all form variables are getting posted.
The PHP code returns: jQuery11020900643879813015_1397599599587({"msg":"1"})
Yet the error indicating the callback was not called is thrown.
How does the request looks like on the server side?
I have a working example which is very similar to what you have. The only difference is that the content type I am replying with is:
'text/javascript'
Also, my JSONP message includes a semicolon at the end (which I think is not really a cause for failure).
returnJSONP = $_REQUEST['callback']. '('.json_encode($data).');';
If you were able to resolve, could you please post the solution?
I gave up trying to get this working and, instead, posted to a local php script which then used CURL to post to the remote server. I echo the CURL results back to the jQuery function and all works well.

Categories