Ajax POST request in JSON doesn't work - ajax

I try to send an HTTP POST request from ajax to PHP, but I have a syntax error that I don't understand..
Is there anyone who can help me ?
index.php
var key = "keytest";
$.ajax({
url: 'requests.php',
type: 'post',
contentType: 'application/json',
dataType: 'json',
data: '{"uniqueKey" : '+key+'}',
success:function( rep ) {
$('#content').html(rep.content);
},
error:function(a,b,err){
console.log(err);
}
});
requests.php
header('Content-type: application/json');
$uniqueKey = filter_input(INPUT_POST, 'uniqueKey');
$key = "newKey";
$retour = array('key' => $key);
echo json_encode($retour);

Don't build JSON by hand, use JSON.stringify
data: JSON.stringify({uniqueKey: key}),
Php does not populate $_POST(INPUT_POST) when the request body is JSON, only for application/x-www-form-urlencoded or multipart/form-data
To get json you'll have to read it from php://input
$json = file_get_contents('php://input');
$obj = json_decode($json);
$uniqueKey = $obj->uniqueKey;
Also you code only responds with a key value but the ajax request expects a content value. You should change the dataType to text to see if you get back what you expect.
$.ajax({
url: 'requests.php',
type: 'post',
contentType: 'application/json',
dataType: 'text',
data: JSON.stringify({uniqueKey: key}),
success:function( rep ) {
$('#content').html(rep);
},
error:function(a,b,err){
console.log(err);
}
});

Related

Wordpress returns 400 Bad Request on ajax call with fetch API

I am making a Ajax call to the admin-ajax.php with a fetch API syntax. Here is the code that calls the back-end script:
fetch(ajax_obj.ajaxurl, {
method: "POST",
mode: "cors",
cache: "no-cache",
credentials: "same-origin",
body: JSON.stringify(this.data),
headers: {
"Content-Type": "application/json"
}
})
and getting 400 Bad Request response.
Can someone tell me where does this request is not right?
When checking the Network Development Tools in chrome, I can see that the body that is sent is ok, the url is also ok...
... and as far as I know 4xx status codes are for errors on the client, so I don't even look on the server side code... if I am wrong please give me feedback on this...
Actually, I had jQuery ajax call like this:
this.data = {
'action': 'ajax_product_query',
'locations': this.locations,
'type': this.category != '' ? this.category : [],
'all-locations': this.filters['locationFilter'].all.checked,
'page': ajax_obj.current_page
};
$.ajax({
url: ajax_obj.ajaxurl,
method: 'post',
dataType: 'json',
data: this.data,
beforeSend: function(xhr) {
button.innerHTML = 'Loading...';
},
success: (data) => { ...
... and it worked like a charm...
Than, willing to remove jQuery dependency, wanted to turn the jQuery ajax call into Fetch API syntax like this:
fetch(ajax_obj.ajaxurl, {
method: "POST",
mode: "cors",
cache: "no-cache",
credentials: "same-origin",
body: JSON.stringify(this.data),
headers: {
"Content-Type": "application/json"
}
})
.then(response => response.json()) ...
And than the requests turned into 400 Bad Requests...
Thanks!
Because after JS fetch 'POST' request you can't get $_POST data in Php. Dirty solution. You could add this code in u "/wp-admin/admin-ajax.php" to resolve this:
if ( !empty( trim( file_get_contents("php://input" ) ) ) ) {
$post = trim(file_get_contents("php://input"));
$_POST = ( array ) json_decode( $post );
$_REQUEST['action'] = $_POST['action'];
}
Or try to find a better solution.
P.S. Sorry for my English

Ajax call from extjs to Yii action url not showing post data

I am trying to pass data to yii controller through ajax.
This is my ajax code in extJs:
Ext.Ajax.request({
url:action_url,
type: 'POST',
dataType: 'json',
data:{insurance: insurance_id},
success:function(res){
console.log(res);
},
In Yii Controller :
public function actionTest()
{
$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
if(Yii::$app->request->isAjax)
{
$data = Yii::$app->request->post();
$response->data = ['data' => $data];
} else {
$response->data = ['fail' => 'failed'];
}
return $response;
Yii::$app->end();
}
I am getting the response as :
{request: {…}, requestId: 6, status: 200, statusText: "OK",…}
responseText:"{"data":[]}"
I am stuck with this. please help.
Added _csrf with other parameters.
Ext.Ajax.request({
url:action_url,
method: 'POST',
dataType: 'json',
params:{insurance: insurance_id, _csrf : csrf_tok}
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
success:function(res){
console.log(res);
},

Laravel 5.4 not able to parse FormData javascript object sent using Jquery Ajax

Lately I've been trying to solve an issue with no luck, basically I'm trying to submit a form to the server using AJAX, the form has files, so I'm using the FormData javascript object in JQuery 1.12. The data arrives to the server but in I way I don't know how to format it.
This is my AJAX function:
function saveMenu(id){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_method', 'PUT');
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
$.ajax({
type: 'PUT',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{url('myUrl')}}",
data: formData,
enctype: 'multipart/form-data',
processData: false,
success: function(response) {
toastr.success('Yai! Saved successfully!')
},
error: function(response) {
toastr.error('Oh oh! Something went really wrong!')
},
complete: function() {
$( "#form-wrapper" ).toggleClass( "be-loading-active" )
}
});
}
and when I perform a dd($request->all()); in my controller I get something like this:
array:1 [
"------WebKitFormBoundaryRCIAg1VylATQGx46\r\nContent-Disposition:_form-data;_name" => """
"_token"\r\n
\r\n
jtv4bnn8WQnP3eqmKZV3xWka2YOpnNc1pgrIfk0D\r\n
------WebKitFormBoundaryRCIAg1VylATQGx46\r\n
Content-Disposition: form-data; name="blocks[43][title]"\r\n
\r\n
...
Things I've tried:
Set the HTTP verb to POST. Same result.
Set the AJAX contentType: false, contentType: application/json. Empty response.
Remove enctype: 'multipart/form-data'. Same response.
Any help is appreciated.
This fixed it for me
data: form_data,
contentType: false,
processData: false,
processData: false prevents jQuery from parsing the data and throwing an Illegal Invocation error. JQuery does this when it encounters a file in the form and can not convert it to string (serialize it).
contentType: false prevents ajax sending the content type header. The content type header make Laravel handel the FormData Object as some serialized string.
setting both to false made it work for me.
I hope this helps.
$('#my-form').submit(function(e) {
e.preventDefault();
var api_token = $('meta[name="api-token"]').attr('content');
form_data = new FormData(this);
$.ajax({
type: 'POST',
url: '/api/v1/item/add',
headers: {
Authorization: 'Bearer ' + api_token
},
data: form_data,
contentType: false,
processData: false,
success: function(result,status,xhr) {
console.log(result);
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
also remember to use $request->all(); $request->input() excludes the files
I've been trying to debug that for 2 hours and i found out that method PUT is not working with formData properly.
Try changing
type : "PUT"
into
method : "POST"
Then change your method on your backend from put to post and you'll see the difference.
I used below codes to test it
$("#menu-form").submit(function (){
var fd = new FormData();
fd.append('section', 'general');
fd.append('action', 'previewImg');
fd.append('new_image', $('.new_image')[0].files[0]);
$.ajax({
method : 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token()}}'
},
url: "{{url('upload-now')}}",
data : fd,
contentType: false,
processData: false,
success: function(response) {
console.log(response);
},
});
return false;
});
And in my controller
public function test(Request $request){
dd($request->all());
}
Ill try to research more about this issue.
Laravel 7,
if use method PUT in ajax, you can follow
1. change method method: 'PUT' to method: 'POST'
2. add formdata.append with _method PUT like this example :
$('#updateBtn').click(function(e){
e.preventDefault();
var frm = $('#tambahForm');
frm.trigger("reset");
$('.edit_errorNama_kategori').hide();
$('.edit_errorGambar').hide();
var url = "/pengurus/category/"+$('#edit_id').val();
var formdata = new FormData($("#editForm")[0]);
formdata.append('_method', 'PUT'); //*** here
$.ajax({
method :'POST', //*** here
url : url,
data : formdata,
dataType : 'json',
processData: false,
contentType: false,
success:function(data){
if (data.errors) {
if (data.errors.nama_kategori) {
$('.edit_errorNama_kategori').show();
$('.edit_errorNama_kategori').text(data.errors.nama_kategori);
}
if (data.errors.gambar){
$('.edit_errorGambar').show();
$('.edit_errorGambar').text(data.errors.gambar);
}
}else {
frm.trigger('reset');
$('#editModal').modal('hide');
swal('Success!','Data Updated Successfully','success');
table.ajax.reload(null,false);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Please Reload to read Ajax');
console.log("ERROR : ", e);
}
});
});
its works for me
Finally I gave up trying to make it work and tried a more vanilla approach, I still don't know the reason why the request is formated like that, but the XMLHttpRequest() function works perfectly and the migration is not a big deal.
The equivalent of the function I posted about would be:
function saveMenu(action){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_token', $('meta[name="csrf-token"]').attr('content'));
var request = new XMLHttpRequest();
request.open("POST", "{{url('myUrl')}}");
request.send(formData);
request.onload = function(oEvent) {
    if (request.status == 200) {
      toastr.success('Yai! Saved successfully!');
    } else {
      toastr.error('Oh oh! Something went really wrong!');
}
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
  };
}
Bit late, but;
This will solve your problem;
var formData = new FormData(document.getElementById('form'));
console.log(...formData);
var object = {};
formData.forEach(function (value, key) {
object[key] = value;
});
Then you can send this object to the server. This is much more readable and works great.
OR
You can simply send this directly;
JSON.stringify(Object.fromEntries(formData));
This is the newer approach.
And don't give up :-)

Doing POST with AJAX returns "Response for preflight is invalid (redirect)"

I am getting a "Response for preflight is invalid (redirect)" everytime I try to execute a POST with AJAX into my webservice. I have downloaded a CORS plug in for my browser and I am able to execute a 'GET' request with it.
$(function(){
var $name = $("#nameTxtB");
var $order = $("#orderTxtB");
var $price = $("#priceTxtB");
var $link = "http://localhost:51834/CoffeeService.svc/addorder";
$("#addButton").on('click', function(){
var $try1 = $price.val();
var $parse = parseInt($try1);
console.log($parse);
var CoffeeOrders = {
Name: $name.val(),
Order: $order.val(),
Price: $parse,
};
console.log(CoffeeOrders);
$.ajax({
contentType : "application/json; charset=utf-8",
dataType : 'json',
type: 'POST',
url: $link,
data: CoffeeOrders,
success: function(){
alert("Order was sucessfully created!");
},
error: function(){
alert("Something went wrong!");
}
});
});
});
The server needs to actually implement the CORS-preflight protocol if you want to make complicated requests like that. It's explained in the standard: https://fetch.spec.whatwg.org/#http-cors-protocol.

Send FormData and String Data Together Through JQuery AJAX

I have the below that uploads an image using JQuery's AJAX function
var id = <?php echo $id; ?>;
var img_data = new FormData($("form")[0]);
$.ajax({
url: 'add.php',
data: img_data,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
I'd like to include a string with the FormData sent. I tried the following, but no luck
data: img_data {id: id},
What's the correct syntax here?
Use append
var img_data = new FormData($("form")[0]);
img_data.append('id', id);
You could create a JSON data object and pass that as application/json and process the data within add.php:
var data = {
id : <?php echo !empty($id) ? $id : "''",
img_data : new FormData($("form")[0])
};
$.ajax({
url: 'add.php',
data: data,
contentType: "application/json",
type: 'POST',
success: function(data){
alert(data);
}
});
Although unconventional, you could also append the data as a query string to the URL with the POST. You'd also need to edit add.php to get this parameter.
$.ajax({
url: 'add.php?id=' + id,
data: img_data,
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});

Resources