Post array is missing json from ajax request - json

I'm trying to make a dynamic document previewer. The user can input certain document header options and based on their account information it will generate a document with a dynamic header. I eventually want to preview a full pdf but I am working on just the header right now.
What I am trying to do is make a page with a form that the user can fill out, then press a button to preview the header.
$.ajaxSetup({
type: 'POST',
timeout: 10000
});
$("#preview_header").click(function(){
var full_url = //appropriate URL
var preview_data = {
"wsid": "default",
"page": "default",
"banner_area1": "default",
"banner_area2": "default",
"banner_area3": "default",
"uid": "default",
"fid": "default",
"cid": "default",
"assignment_type": "default"
};
preview_data.wsid = $("#worksheet_picker").val();
preview_data.page = $("#page_picker").val();
preview_data.banner_area1 = $("#banner_area1").val();
preview_data.banner_area2 = $("#banner_area2").val();
preview_data.banner_area3 = $("#banner_area3").val();
preview_data.uid = $("#member_uid").val();
preview_data.fid = $("#family_id").val();
preview_data.assignment_type = 'family';
preview_data.cid = $("#class_id").val();
var JSONText = JSON.stringify( preview_data );
alert('Full JSON - ' + JSONText);
$.ajax({
async: true,
url: full_url,
data: { previewInfo : JSONText }, //Passes necessary form information
dataType: 'json',
success: function(output){
var reply = output;
if ( reply.status == "success" ){
$("#preview").attr("src", reply.image );
} else {
alert('Failed to create image preview of the assignment.');
}
}
});
});
As far as I can tell, the above method is working fine. It hits the right Codeigniter page and when the ajax method is set to return a hard coded image it works just fine. The AJAX seems to be well formatted but just in case here is what it outputs when I fill out forms with the corresponding values:
Full JSON - {"wsid":"4","page":"1","banner_area1":"link1",
"banner_area2":"link2","banner_area3":"link3",
"uid":"1","fid":"1","assignment_type":"family"}
So first off, let's start with what is working in the corresponding controller method for the ajax reply:
$data = array(
'status' => 'success',
'image' => //static image link
);
$this->output->set_content_type('text/javascript;charset=UTF-8');
echo json_encode($data);
But whenever I try to modify it like so:
$preview_data = json_decode($this->input->post('previewInfo'));
//Got this one
mail('me#gmail.com', 'Start Email', 'Some email' );
//Empty email
mail('me#gmail.com', 'Dump Post', var_dump($_POST));
//Empty email
mail('me#gmail.com', 'Post data', var_dump($preview_data) );
//returns an email with 1 for body
mail('me#gmail.com', 'Post data', print_r($this->input->post()) );
//returns an email with 1 for body
mail('me#gmail.com', 'Post data',
print_r($this->input->post('previewInfo')) );
//returns an email with 1 for body
mail('me#gmail.com', 'Post data', print_r($preview_data) );
$data = array(
'status' => 'success',
'image' => //static image link
);
$this->output->set_content_type('text/javascript;charset=UTF-8');
echo json_encode($data);
The modified one doesn't return the static data either. So it would seem that the post array is not being intialized properly. Anyone see the bug?

If you want to send your Ajax request with the post method, you need to set type to POST in your $.ajax options.
Also, async is true by default, so setting it is not necessary. Additionally, you should consider using .done and .fail as opposed to success and fail, as they are slated to be deprecated very soon.
Like so:
$.ajax({
type: "POST",
url: full_url,
data: { previewInfo : JSONText }, //Passes necessary form information
dataType: 'json'
}).done(function (output, textStatus, jqXHR) {
var reply = output;
if ( reply.status == "success" ){
$("#preview").attr("src", reply.image );
} else {
alert('Failed to create image preview of the assignment.');
}
}).fail(function (jqXHR, textStatus, errorThrown) {
// now you have the XHR, text status, and error to debug with
});

There was 2 problems that lead to the solution to this problem:
1)
As Austin and Gavin said: var_dump and print_r should not be outputting to the browser.
The solution was to debug with firefox extensions / chrome.
2)
$preview_data = json_decode($this->input->post('previewInfo'));
was changed to
$preview_data = json_decode($this->input->post('previewInfo'), true);
The secondy optional parameter of json_decode is to tell the method whether you are expecting an associative object or a list of things. As it happens, I was reading in and wanted an associative array.

Related

Send API data and image but always empty

I'm trying to send a user picture to my api with Slim 3, PHP 7 and JQuery 2.1.1
But when I call api in HTML page then I get couple errors in Apache log, it seems that data arguments are empty and I dont know why.
Someone could help?
-------HTML source code api call
function savePicture(){
var fID = $('#edtIDUser').val();
var fPicture = document.getElementById('img').src;
$.ajax({
type:"POST",
cache:false,
url:"index.php/user_picture/",
timeout:3000,
contentType:"application/json; charset=utf-8",
data:{'id_user': fID, 'picture': fPicture},
dataType:"text",
async:false,
error: function (request, error) {
alert("error");
},
success: function (result) {
alert("ok");
}
});
}
AND API
----API source code
$app->post('/user_picture/', function(Request $request, Response $response) {
$params = $request->getParsedBody();
$iduser = $params['id_user'];
$uploadedFile = $request->getUploadedFiles();
$img = $uploadedFile['picture'];
$data = file_get_contents($img);
$escaped = bin2hex($data);
//TO-DO
}
Error #1: Trying to access array offset on value of type null in $params['id_user']
Error #2: Undefined index 'picture'
Error #3: file_get_contents(): Filename cannot be empty

How to get data from html form?

What is the most modern way to get data from an html form and email it to yourself?
One way could be to have a JQuery .sumbit() event handler on your submit button which would gather all the info from the form and send them to a backed controller which would actually send the email.
JQuery example:
$('form').submit(function(event) {
// get the form data
var formData = {
'name' : $('input[name=name]').val(),
'email' : $('input[name=email]').val(),
'phone' : $('input[name=phone]').val()
};
// process the form
$.ajax({
type : 'POST',
url : 'process.php',
data : formData,
dataType : 'json',
encode: true
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
});
event.preventDefault();
});
The server side could look something like:
<?php
// process.php
$errors = array();
$data = array();
// Validation
if (empty($_POST['name']))
$errors['name'] = 'Name is required.';
if (empty($_POST['email']))
$errors['email'] = 'Email is required.';
if (empty($_POST['phone']))
$errors['phone'] = 'phone is required.';
if ( ! empty($errors)) {
$data['success'] = false;
$data['errors'] = $errors;
} else {
// Send email here
$data['success'] = true;
$data['message'] = 'Success!'
}
?>
In this way you would decouple client side logic (gather form data) and backend logic (send the email).

Ajax get request succeds on localhost but fails online

I'm try to get data via an ajax get request in Wordpress and I wrote a script in javascript and another in php to handle it.
The code for javascript is the following:
window.loadServices = function loadServices(){
var data = {
action: 'get_services',
perpage: '6',
};
$.ajax({
type: 'GET',
url: sendbooking.ajaxurl,
data: data,
dataType: 'json',
success: function (response) {
post = response.data;
console.log(response);
$.each(post, function(){
elem = $(this)[0];
media = elem._links['wp:featuredmedia']
var media_href;
$.each(media, function(){
media_href = $(this)[0].href;
})
// console.log(elem);
var image;
$.ajax({
type: 'GET',
url: media_href,
dataType: 'JSON',
success: function(data){
image = data.source_url;
},
async: false,
})
$('.services .elements .elements-container').append(
$('<div />', {
class: 'loader',
}).append(
$('<img />', {
src: '/wp-content/themes/farmhouse/assets/images/loader.gif'
})
)
)
setTimeout(function(){
$('.loader').fadeOut();
}, 2000);
$('.services .elements .elements-container').append(
$('<div />', {
class: 'element '+elem.type,
}).append(
$('<a />', {
href: elem.link
}).append(
$('<div />', {
class: 'element-image',
}).append(
$('<img />', {
src: image,
})
)
)
).append(
$('<h5 />', {
class: 'element-title',
}).append(
$('<a />', {
href: elem.link,
text: elem.title.rendered
})
)
)
)
setTimeout(function(){
$('.loader').remove();
}, 2000);
})
},
});
}
This is instead the code for php:
if(!function_exists('get_services')):
function get_services(){
$data = $_GET;
$json_feed = get_site_url() . '/wp-json/wp/v2/service?per_page='.$data['perpage'];
$json = file_get_contents($json_feed);
$json_decoded = json_decode($json);
wp_send_json_success($json_decoded);
}
add_action('wp_ajax_get_services', 'get_services');
add_action('wp_ajax_nopriv_get_services', 'get_services');
endif;
The problem I'm having is that on localhost, this works fine, I get the content I need, without any problem. When I'm going to deploy the site on line, the ajax doesn't retrieve anything. Throwing console.logs, I noticed that the scripts fail when getting data from the api url (file_get_contents), but if you go there directly via browser's address bar, or through postman, data are served correctly. (You can test: http://www.dsoftwarelab.it/ilpiastrino/wp-json/wp/v2/service?per_page=6).
I really don't know how to solve it, since I've really tried everything.
Case 1 : You don't have access rights on server.
If you have root access, edit php.ini, usually located at /etc/php.ini.
If you dont have root access, try to add ini_set('allow_url_fopen', 'On'); or ini_set('allow_url_fopen', '1');.
If you can't see php.ini, try using phpinfo() in a PHP script to find the php.ini location.
Case 2 : You have miss the SSL parameter in .
$url= 'https://example.com';
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
);
$response = file_get_contents($url, false, stream_context_create($arrContextOptions));
Case 3 : 403 FORBIDDEN
The server responds with an "403 FORBIDDEN" status code. So file_get_contents() works fine, but the server you are trying to access (or a proxy or something in between) dont allow it.
Do not convert json to array. comment this line $json_decoded = json_decode($json);
if(!function_exists('get_services')):
function get_services(){
$data = $_GET;
$json_feed = get_site_url() . '/wp-json/wp/v2/service?per_page='.$data['perpage'];
$json = file_get_contents($json_feed);
//dont need this line
//$json_decoded = json_decode($json);
wp_send_json_success($json);
}
add_action('wp_ajax_get_services', 'get_services');
add_action('wp_ajax_nopriv_get_services', 'get_services');
endif;

CGI API to POST using $.ajax() instead of $.getJSON() RPGLE IBM i PASE environment

What CGI API can you use to replace $.getJSON() with $(ajax)...POST. GET is used for everything (ie: GET, PUT, POST, DELETE) when using CGIDEV2 in an IBM i environment? I dont want to pass my parameters the traditiontal way eg: $('[name="EMAIL"]').val() rather I want to pass JSON object string eg: {"form" : [{ "email": "yardpenalty#yahoo.com"}]}.
We are able to perform PostToGet callbacks using the $.getJSON() using CGIDEV2 but I can't use $.ajax in its fullest. Here is what we do now which is all GET requests
PHP/JS:
// load all parameters
data = 'INSTANCE=<?echo trim($PATH_INSTANCE)?>' +
'&FUNCTION=<?echo urlencode(trim($FUNCTIONCODE))?>' +
'&USER=' + $('[name="USER"]').val() +
'&CONTACT=' + w$('[name="CONTACT"]').val() +
'&EMAIL=' + $("input[name='EMAIL']").val() +
'&MSG=' + $('[name="MSG"]').val() +
'&TYPE=' + $('[name="TYPE"]').val();
// Call the RPG REST JSONP program
$.getJSON( "http://www.domain.com:8082/rest/RPGLEPGM?callback=?",data )
.done(function( json ) { ... }
//Domain is actually
http://www.domain.com:8081
RPGLE PGM:
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // callback
p#Function = cgiParseGet('FUNCTION');
Endsr;
But I want to be able to use the other AJAX methods doing various actions such as simply updating records .post()/.ajax() on the fly or simple .get() ajax calls without creating a callback. I don't want to have to use getJSON every time I use ajax not to mention its bad practice to POST on a GET, but from what I understand the .getJSON() provides JSONP functionality while the others do not by default.
EDIT: We do have our ajax RPGLE PGMS on a different port than the actual website so JSONP is necessary and the client knows its JSONP because we pass the callback function back.
Since our ajax RPGLE PGM CALLS are on a different port than the PHP requests (think different domains on a host server) this qualifies as cross-domain requests; therefore, we must pass the &callback=? function/wrapper back to the client using JSONP (or Cors if security is an issue). I found a really good piece on JSONP here on SO and this is exactly what this ajax call is using.
RPGLE the jQuery ajax requests are made possible by using some sort of CGI API accessible on your OS/400 - IBM i Web environment. When calling (CALLB or CALLP) an RPGLE PGM using ajax we are actually making a procedural call, but when using global temps we are actually making a SQL Procedural CALL which is way more expensive in terms of resources which is why Web Services are becoming more popular.
It is more practical to not only pass javascript objects from the form data on request but to return JSON objects with Ajax requests than storing global temp data in the db2 environment and processing it into a PHP array on the response.
By processing the JSON string on the client instead of using both server memory and drive space and disk read/writes necessary for PHP arrays and global temp files we are really able to take advantage of more modern web design practices.
Here is a working example of using $.ajax/PHP/RPGLE correctly without using $.getJSON():
<script>
$(document).ready(function(){
GetEmail("#email", '<?php echo trim($USER)?>', '<?php echo $PATH_INSTANCE?>');
FormValidation();
});
function FormValidation(){
//Variables created without the keyword var, are always global, even if they are created inside a function.
var form = $('#<?echo $PAGEID?>');
var FormError = $('.alert-danger',form);
var success = $('.alert-success',form);
form.validate({
focusInvalid: false, // do not focus the last invalid input
onkeyup: false,
ignore: ".ignore", //required for hidden input validation ie: hiddenRecaptcha
rules:{
"TYPE": {
required: true,
},
"MSG": {
required: true,
rangelength:[40,1000]
},
"CONTACT": {
required: {
depends: "#newuser:checked"
}
},
"EMAIL": {
required: true,
email: {
depends: function() {
if(!$("#newuser:checked"))
return true;
else
return false;
}
},
HTH_TelephoneEmail: {
depends: function() {
if($("#newuser:checked"))
return true;
else
return false;
}
}
},
hiddenRecaptcha: {
required: function () {
if (grecaptcha.getResponse() == '') {
return true;
} else {
return false;
}
}
}
},
messages: { // custom messages for form validation input
"TYPE": {
required: 'Please select an option as it pertains to your inquiry'
},
"MSG": {
required: 'Please provide some content as it pertains to your inquiry'
},
"CONTACT": {
required: "Please enter a contact person or company"
},
hiddenRecaptcha: {
required: function() {
$(".g-recaptcha:first").tooltip("enable").tooltip("show");
}
}
},
showErrors: function(errorMap, errorList) {
// Clean up any tooltips for valid elements
$.each(this.validElements(), function (index, element) {
element = $(element);
NoError_ToolTip(element);
});
// Create new tooltips for invalid elements
$.each(errorList, function (index, error) {
element = $(error.element);
message = error.message;
Error_ToolTip(element,message);
});
},
invalidHandler: function (event, validator) { //display error alert on form submit
success.hide();
$(document).scrollTop( $(".form-body").offset().top );
},
submitHandler: function () {
Submit_Complete();
}
});
function Submit_Complete(){
var obj = form.serializeObject();
console.log(obj);
$(".g-recaptcha:first").tooltip("disable").tooltip("hide");
$('.shell').html('<div class="loading"><span class="caption">Sending...</span><img src="/images/loading.gif" alt="loading"></div>');
$.ajax({
type: "POST",
url: "http://www.domain.com:8082/rest/RPGPGM2?callback=?",
data: obj,
//contentType: "application/json; charset=utf-8",
dataType: "jsonp"}).
done(function(data){
$(".shell").html('<label class="msg xs-small">' + data["MESSAGE"] + '</label><br><br><br><br><br><br><br><br><br>'+
'<div class="caption right">'+
'Home <i class="fa fa-home"></i>'+
'</div>');
}).
fail(function(){
$(".shell").html("<label class='msg xs-small'>We're Sorry!<br><br><br><br><span class='text-danger'>Unfortunately this inquiry cannot be processed at this time." +
"<br>Please try again at a later time or give us a call at:</span><br><br>+1.800.406.1291</label><br><br><br><br><br><br><br><br><br>"+
'<div class="caption right">'+
'Home <i class="fa fa-home"></i>'+
'</div>');
});
}
}
/**
* Serializes form data/objects. This actually creates a javascript object which our CGIAPI is capable of handling!
*
*/
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
var $value = '';
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
</script>
We can make RESTful calls by using some type of CGI API such as QtmhRdStin or by creating Web Services. This solution is of the former.
Here is a list of the basic CGI APIs:
RPGLE PGM:
// $Incoming: Test and load the incoming parameters
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // never delete - unique key for the request
p#UserID = cgiParseGet('USER');
if (%scan(#lf:p#UserID) <> 0);
p#UserID = *blanks;
endif;
p#Instance = cgiParseGet('INSTANCE');
if (%scan(#lf:p#Instance) <> 0);
p#Instance = *blanks;
endif;
p#Function = cgiParseGet('FUNCTION');
p#Contact = cgiParseGet('CONTACT');
if (%scan(#lf:p#Contact) <> 0);
p#Contact = *blanks;
endif;
p#Email = cgiParseGet('EMAIL');
p#Msg = cgiParseGet('MSG');
p#Related = cgiParseGet('TYPE');
exsr $InzSr;
Endsr;
Begsr $Outgoing;
// Tell Consumer that a JSON string will be sent
ajx_data = 'Content-type: text/javascript' + CRLF + CRLF; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = %trim(callback) + '(' + %char(LBrace); // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = '"MESSAGE":"' + %trim(p#message) + '"';
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);
// load the final right brace to complete the JSON string
ajx_data = %char(RBrace) + ');'; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err); // DO NOT CHANGE THIS LINE!!!
Endsr;
****NOTE****
If we can't serialize our form directly we must build a javascript object like this:
var obj = {USER : localProfile,
INSTANCE : "HTHACKNEY",
PAGE : $('select[name="PAGE"]').val(),
TITLE : $("input[name='TITLE']").val(),
HTML : html,
STARTDATE : $("input[name='STARTDATE']").val(),
ENDDATE : $("input[name='ENDDATE']").val(),
ARCHIVE : $("input[name='ARCHIVE']").val(),
ACTIVE : $("input[name='ACTIVE']").val(),
URGENT : $("input[name='URGENT']").val(),
AUTHLST : authStr};
$.ajax({
type: "POST",
url: "http://webservices.hthackney.com/web054S?callback=?",
data: data,
dataType:'jsonp'
}).done({ //do something on success });
Unfortunately you can POST using JSONP but you cannot read the header response.
I FINALLY found the solution to executing both db2 and ajax requests on a single DOMAIN.
SOLUTION HERE
If you need to perform AJAX requests on the SAME DOMAIN in an IBMi environment w/apache/PASE you need the following ScriptAlias and two directives in your http.conf file:
ScriptAliasMatch /rest/([0-9a-zA-Z]+$) /qsys.lib/rest.lib/$1.pgm
<Directory /qsys.lib/obj.lib/>
order allow,deny
allow from all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI +Includes -Indexes +MultiViews
CGIConvMode %%MIXED/MIXED%%
</Directory>
<Directory /qsys.lib/rest.lib>
CGIConvMode %%EBCDIC/EBCDIC%%
Order Allow,Deny
Allow From all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI -FollowSymLinks -SymLinksIfOwnerMatch +Includes -IncludesNoExec -Indexes -MultiViews
</Directory>
rest.lib member is where all of the ajax rpgle pgms reside.
obj.lib is where all CALL WEBXXX for db2 calls in PHP are located.
Now you are able to call AJAX requests under the /rest/$1PGM pattern.
For instance:
$.ajax({
type: "POST",
url: "http://www.domain.com/rest/WEB055S",
data: obj,
contentType: "application/json; charset=utf-8"
).
done(function(data){
$("#signupForm .loading").addClass("hidden");
//Successful Submit!
if(typeof data.MESSAGE != "undefined"){
clicked = 0;
$("#ok_msg").html(data.MESSAGE).show();
}
else{//ERROR
//console.log(data.ERROR);
$("#attendee #hth_err_msg").html(data.ERROR).show();
$('.add-attendee').addClass('hidden');
$('.edit-attendee').addClass('hidden');
}
}).
fail(function(){
$("#hth_err_msg").html("We're sorry, you're request cannot be processed at this time. It is likely the corporate system is under maintenance.").show();
});

Data not getting saved using JQuery.ajax

I want to save data from Textbox on Button click. I am using JQuery AJAX for this task like below. Please note that I made this tags inside theme function.
function theme_user_post_block($vars)
{
$themeUserCommentInput ='';
$themeUserCommentInput .= '<textarea id="txt_1"rows="1" cols="50"></textarea>';
$themeUserCommentInput .= '<input type="submit" value="Post Comment" align="center"
class="btnPostComment" id="btn_1" />'
return $themeUserCommentInput;
}
This able to show me Textbox and Button inside the page. Now here is my JS code:-
(function($)
{
Drupal.behaviors.PostComment= {
attach: function (context, settings) {
$('.btnPostComment', context).click(function (event) {
var post = "&newcomment=Comment1&logid=log1";
jQuery.ajax({
url: 'postcomment',
type: 'POST',
dataType: 'json',
data: post,
success: function (data) { alert(data); },
error: function(jqXHR, textStatus, errorThrown){alert(textStatus +
errorThrown);}
});
});
}
}
})(jQuery);
Next I create a Menu Page with URL Name as follows:-
function postcomment_menu(){
$items=array();
$items['postcomment']=array(
'title'=>t(''),
'type'=> MENU_CALLBACK,
'page callback' => 'user_comment_post',
'access arguments' => array('access content'),
);
return $items;
}
function user_comment_post(){
global $user;
$cid = db_insert('user_comment')
->fields(array(
'comment_user_id' => $user->uid,
'reference_id' => $_POST['logid'],
'comment_desc'=>$_POST['newcomment'],
'createdon'=>REQUEST_TIME,
))
->execute();
if($cid!=0)
{
//GetUserComments($i);
drupal_json_output("success");
}
}
So I have done all things that is required for jQuery+Ajax Submit functionality. When I press "Post Comment" button it gives me error in alert says "errorundefined". The alert shows as a result of error inside the jQuery.AJAX function. Also the custom menu callback is also not getting called.
post the data as object...and make sure your post url is correct.. the url doesn't looks correct
var post = {newcomment: 'Comment1',logid:'log1'};
I came to end of this problem. I dont know what might be the resolution or root cause but I end up solving this problem. I meagre add one line(async: false) in my jQuery.ajax function and everything works perfectly. Please see the code below:
jQuery.ajax({
url: 'postcomment',
type: 'POST',
dataType: 'json',
async: false,
data: post,
success: function(data) {
alert(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus + errorThrown);
}
});
If anyone have any knowledge as what this line will do then please share with us.