How to pass data to PHP via AJAX POST - javascript

I'm trying to pass data via AJAX to a PHP file, but it's returning NULL.
Here's the AJAX code (with all 'val()' getting a value correctly [I've tested it]):
$.ajax({
url: '../utilities/atualizar_ferias.php',
method: 'POST',
cache: false,
contentType: false,
processData: false,
data: {
data_inicio: inicio_target.val(),
data_fim: fim_target.val()
},
success: function(resultado){
console.log(resultado);
}
})
Here is the PHP code to receive the data:
<?php
$dados = filter_input_array(INPUT_POST, FILTER_DEFAULT);
var_dump($dados);
Does anyone have any idea why I'm getting NULL?

Your PHP script isn't returning any sort of valid JSON. It's just doing a var_dump of the result of filter_input_array. According to the docs on that function, the return value is as follows:
Return Values
An array containing the values of the requested variables on success. If the input array designated by type is not populated, the function returns null if the FILTER_NULL_ON_FAILURE flag is not given, or false otherwise. For other failures, false is returned.
An array value will be false if the filter fails, or null if the variable is not set. Or if the flag FILTER_NULL_ON_FAILURE is used, it returns false if the variable is not set and null if the filter fails. If the add_empty parameter is false, no array element will be added for unset variables.
I suggest you inspect in your browser what is being returned as the response to your POST operation to the server. You should see that it is the output of the PHP var_dump function which is not valid JSON, so your JS won't parse it.
You may also need to set options on your AJAX request to specify what sort of result you expect: text, json, etc.

Related

Extract object from JS script loaded with synchronous jQuery ajax call

I am trying to get use an object from a script loaded synchronously using Ajax via jQuery.
From this script I am trying to load an object which looks like this from a script called map_dropdowns.js which returns the object options:
{curr_cat: "RELATIONSHIP"
curr_subcat: " Population in households"
curr_total: "Total"}
My code for the script with the ajax is here:
<script>
$.ajax({
type: "GET",
url: "../scripts/map_dropdowns.js",
dataType: "script",
async: false,
success: function(data){
console.log(data);
}
});
console.log(options); //returns `Object{}` in the console, and only shows values when expanded
options["curr_cat"]; //returns undefined
console.log(Object.keys(options)); //returns an empty array []
</script>
In the original script, the keys and values within options can be accessed perfectly fine. console.log in Chrome shows its contents fully without needing to be expanded (Object {curr_cat: "RELATIONSHIP", curr_subcat: " Population in households", curr_total: "Total"}), and Object.keys() works just fine.
After it is loaded onto the page with the Ajax function, however, trying to access the values using the keys comes up undefined, Object.keys turns up an empty array [], and the key:value pairs are only shown in the console when I click on the object, with it otherwise showing only Object {}.
I am pretty sure that I need to do something in the success function of the Ajax, but I am not sure what after a lot of trial and error.
Thanks!
Loading JS code via AJAX is always a little hit and miss. It's usually a much better idea to load the data either as HTML, XML or JSON, and then deal with it as required once the AJAX request completes.
In your case, as you're attempting to load an object, JSON would be the most appropriate. If you change your map_dropdowns.js file to return data in this format:
'{"curr_cat":"RELATIONSHIP","curr_subcat":"Population in households","curr_total":"Total"}'
You can then make your async request to get this information from this file:
$.ajax({
type: "GET",
url: "../scripts/map_dropdowns.js",
dataType: "json",
success: function(data){
console.log(data.curr_cat); // = 'RELATIONSHIP'
console.log(data.curr_subcat); // = 'Population in households'
console.log(data.curr_total); // = 'Total'
}
});

Using FormParams with Jersey and jQuery

Seems like this is an infrequently answered questions that's frequently asked. The documentation is somewhat ambiguous.
I want to post a set of parameters as described below.
Web service:
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(#FormParam("param") String param){
// code..
}
javascript:
//var paramData = {"startDate":$("#startDate").val()};
var paramData = {startDate:$("#startDate").val()};
$.ajax({
type : 'POST',
url : 'mysite.com/post',
data: paramData,
contentType: 'application/x-www-form-urlencoded',
processData: false,
});
I've changed the contentType to false, tried serializing and stringfying the param data, etc. Either the argument comes in as null in the service or it returns an unsupported media type HTTP error code.
You are doing it wrong...
1. By default, your contentType will be application/x-www-form-urlencoded, so it's not necessary to specify it.
2. Why are you using processData: false? you should read the documentation from here:
http://api.jquery.com/jQuery.ajax/
processData (default: true)
Type: Boolean
By default, data passed in
to the data option as an object (technically, anything other than a
string) will be processed and transformed into a query string, fitting
to the default content-type "application/x-www-form-urlencoded". If
you want to send a DOMDocument, or other non-processed data, set this
option to false.
3. Since processData is true by default and you don't need this to be false then it's not necessary to specify it.
4. You are just passing an Object as the data but where did you specify the param since that's the name that you used for your method? Take a look: public Response post(#FormParam("param") String param)
5. Since your param is a String you will need to convert your Object into a queryString (same as if we were serializing a form) and you can do it easily with jQuery, you should read the following: http://api.jquery.com/jquery.param/
6. So, at the end your code must look like this:
var data = {
name: 'Oscar',
lastname: 'Jara'
};
$.ajax({
type: 'POST',
url: 'rest/service',
data: {
param: $.param(data)
}
});
7. Now, if you print what your param variable contains inside your REST service, you will get this:
name=Oscar&lastname=Jara

Does $.ajax automatically execute script, if the data returned is javascript?

I use a single JS file to post all my data back to my server, using:
$.ajax({
url: "/backend/post.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(response, status, xhr) // A function to be called if request succeeds
{
var ct = xhr.getResponseHeader("content-type") || "";
if(ct.indexOf("text/plain") > -1){
alert(response);
console.log('text - response');
}
if(ct.indexOf("text/javascript") > -1){
//eval(response);
console.log('javascript - response');
}
}
});
It goes through a whole load of functions on the server side but eventually gets to this one: output_javascript("alert('item added');");
function output_javascript($script)
{
header("content-type:text/javascript");
echo $script;
}
The idea was to have the $.ajax function display text or execute script from the server.
When $.ajax gets the response from output_javascript("alert('item added');"); then it executes the code twice. When I comment out the code to execute in the success function:
$.ajax({
url: "/backend/post.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(response, status, xhr) // A function to be called if request succeeds
{
}
});
Then it only executes the response once. Making me believe that $.ajax executes the code before returning the script in the response variable.
Is this true, or am I not understanding $.ajax correctly ? If I am misunderstanding the $.ajax function, could someone please tell me how to resolve this problem?
Yes, ajax will execute returned JavaScript code. We can see this in the documentation:
dataType (default: Intelligent Guess (xml, json, script, or html))
Type: String
The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). The available types (and the result passed as the first argument to your success callback) are:
So if you don't specify dataType, jQuery will figure it out from the response. Okay, but what does it do with a "script" value? Further down:
"script": Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string parameter, "_=[TIMESTAMP]", to the URL unless the cache option is set to true. Note: This will turn POSTs into GETs for remote-domain requests.
And later in the discussion:
If script is specified, $.ajax() will execute the JavaScript that is received from the server before passing it on to the success handler as a string.
All of this is easily found in the documentation by simply searching for the word "JavaScript" on the page.

jQuery AJAX POST - data doesn't get sent

$.ajax({
url: "/Configuration/AddServersAdvancedSelect",
type: "POST",
data: { selectedOUs: that.getByDataSelected() },
async: false,
dataType: "html",
success: result => {
cont.setTabContentFromHtmlString(result, 1);
cont.tabClicked($("td[data-value='1']").get(0));
},
error: (xhr, ajaxOptions, thrownError) => {
//
}
});
EDIT: I came back to work today and it magically started working. I guess that's something
This is my ajax request towards the server. For some reason the data doesn't get selected. The getByDataSelected function works just like it should and reuturns good values. The Controller method has the name selectedOUs and everything matches. Does anybody have any idea as to why this ajax POST doesn't send data?
jQuery defines the data parameter as
Type: PlainObject or String or Array
Data to be sent to the
server. It is converted to a query string, if not already a string.
It's appended to the url for GET-requests. See processData option to
prevent this automatic processing.
Object must be Key/Value pairs.
If value is an Array, jQuery serializes multiple values with same key
based on the value of the traditional setting (described below).
I'd be willing to bet that your return value of that.getByDataSelected() is not consistent with the expected parameter if it isn't getting sent.
In this case, your error function should be receiving an Internal Server Error [500]

Filter JSON response on a jQuery ajax request, for XSS text

I am falling into a silly issue where the server is giving JSON response with XSS safe text added.
The server gives only 2 kinds of response:
HTML page with hidden input field that contains the value I want
JSON String with the value which can be preferably converted to JS
Object.
The problem is, for preventing JavaScript XSS attacks, the JSON response is made like this:
while(1);{
"name": {
"abc": "123",
...
}
}
So this goes to parseerror in jQuery ajax method and therefore in the error callback.
How do I fix this?
Also, I tried putting a hook in the error function and change the JSON data:
error: function(jqXHR) {
removeJSCode (jqXHR.responseText);
}
// ...
function removeJSCode(json) {
.. Code to filter the response
}
But this does not work.
jQuery's $.ajax has dataFilter property in its configuration. Pass it a function and it runs after jQuery receives ajax data, but before jQuery has a chance to touch it.
The function is provided the string response as first argument and data type as second argument. The second argument will depend if you passed dataType in the configuration.
There, you can use .replace('while(1);','') and return the string from the function for jQuery to parse.
$.ajax({
...
dataType : 'json',
dataFilter : function(response,type){
//if not JSON, don't do anything with it
if(type !== 'json') return response;
//otherwise, replace and return
return response.replace('while(1);','');
}
...
});

Categories