AJAX postdata working on localhost but not on (Apache) server - ajax

I identified an issue with postdata not being sent through AJAX on my server. To debug it, I wrote the following fairly minimalistic piece of javascript to test a simple AJAX call :
function my_custom_ajax(target_page, target_element , postdata_contents) {
// Sending the XMLHttpRequest as postdata
var xhr = new XMLHttpRequest();
xhr.open("POST", target_page, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xhr.setRequestHeader("Content-length", postdata_contents.length);
xhr.setRequestHeader("Connection", "close");
xhr.send(postdata_contents);
// Waiting for the request to return
xhr.onreadystatechange = return_data;
// If all went well, we update the target element
function return_data()
{
if(xhr.readyState === 4)
{
if(xhr.status === 200)
{
// We update the target element
document.getElementById(target_element).innerHTML = xhr.responseText;
}
// Throw error in case of 404 or such
else
document.getElementById(target_element).innerHTML = "XHR can't be loaded";
}
// Throw error in case request got interrupted or didn't work out
else
document.getElementById(target_element).innerHTML = "XHR error";
}
}
It is called with the following HTML :
<div onClick="my_custom_ajax('test_page.php?xhr','my_id','postdata_test');">
Click me
</div>
<div id="my_id">
xhr response will appear here
</div>
And calls a PHP page which contains only this :
exit(var_dump($_POST));
When running this piece of code in my Apache localhost or another Apache server I own, it does pass whatever is in postdata_contents as postdata. The exit(var_dump($_POST)); does show that it works properly, and does print the value of the postdata I passed to it.
However, when running this same piece of code on the Apache server where it does not work, all I get is « array(0) { } », as in, no postdata is passed according to the PHP file.
Here is Firefox's dev tool view of the request details (in french, sorry, but should be obvious what is what) :
The debug tool shows that the postdata contents are properly being sent :
However, the returned content show that the postdata was somehow not passed :
On my localhost and my other Apache server, everything is exactly the same until the very last step, where the postdata is properly passed (the var_dump message is styled but you can easily see the gist of it : postdata_test is part of $_POST) :
After hours of fiddling with the configuration of this Apache server and trying all of the debug methods and breakpoints I could think up, my nerves are too worked up to continue thinking about this rationally for now. As I have no option of using another server or just copypasting my local Apache configuration file on the new server, I defer this question to you all, hoping that somebody can figure it out or once encountered something similar.
Thanks in advance,
Eric B.

Solved it myself by accident, I had mod_dumpio activated on the server and it started working once I turned it off.
I do not know what mod_dumpio was doing to deny XHR POST but not generic HTTP POST, but at least that's solved.
Hope this will help someone else some day.
(on a sidenote, I realize the postdata query in my example was malformed, should have been « postdata_test= » instead of « postdata_test », so add that equal sign if you are stuck in my situation and want to run the same tests I did)

Related

AJAX response returns current page

I was searching for a similar issue for a while now, but none of the solutions worked for me (and I couldn't find exactly the same issue).
First of all, the website I'm working on is running on Zend Framework. I suspect that it has something to do with the issue.
I want to make a pretty basic AJAX functionality, but for some reason my response always equals the html of the current page. I don't need any of Zend's functionality, the functions I need to implement could (and I'd prefer them to) work separately from the framework.
For testing purposes I made it as simple as I could and yet I fail to find the error. I have a page "test.php" which only has a link that triggers the ajax call. Here's how this call looks:
$('.quiz-link').click(function(e){
e.preventDefault();
$.ajax({
URL: "/quiz_api.php",
type: "POST",
cache: false,
data: {
'test': 'test'
},
success: function(resp){
console.log(resp);
},
error: function(resp){
console.log("Error: " + reps);
}
});
});
And this quiz_api.php is just:
<?php
echo "This is a test";
?>
When I click on the link I get the entire HTML of the current page. "This is a test" can't be found there. I'm also getting an error: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/."
I reckon it has to do with the JS files that are included into this HTML response, but I've also tried setting "async: true" and it didn't help.
I would like to avoid using Zend Framework functions for this task, because I'm not well familiar with it and even making a simple controller sounds rather painful. Instead I want to find out what's causing such behavior and see if it can be changed.
PS: I've also tried moving quiz_api.php to another domain, but it didn't change anything.
I know that it might be an older code but it works, simple and very adaptable. Here's what I came up with. Hope it works for you.
//Here is the html
Link Test
<div id="test_div"></div>
function test(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// This is the php file link
var url = "quiz_api.php";
// Attaches the variables to the url ie:var1=1&var2=2 etc...
var vars = '';
hr.open("POST", url, true);
//Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange =
function(){
if(hr.readyState == 4 && hr.status == 200){
var return_data = hr.responseText;
console.log(return_data);
document.getElementById('test_div').innerHTML = return_data;
}else{
document.getElementById('test_div').innerHTML = "XMLHttpRequest failed";
}
}
//Send the data to PHP now... and wait for response to update the login_error div
hr.send(vars); // Actually execute the request
}
you can change the whole page with a document.write instead of changing individual "div"s

Jade html not updated after a redirect in Express.js

I'm currently having some trouble displaying a flash message in Express.js using Jade's templating engine and connect-flash. I am simply trying to flash an error message when the user tries to add a new User object to my database that already exists. However the flash message is not showing up on my page after calling router.post and redirecting back to the index (code below).
Through various console.logs and debugging, I have found that the data I am posting is indeed posting correctly, and the flash message is being set. What I have found is that on the redirect, all of the correct data is passing to the Jade template, but the variables are not being updated in the file itself. I am now wondering if this is a session related issue, or just something Flash/Jade/Express related that I am completely overlooking?
In the code below I am logging session data as well as setting the flash message to a variable. If the array for the flash message(s) is empty (i.e. on page load), an array is set with a message that says so. If the flash message(s) array contains a flash message, the test array is set with a message that says so.
index.js:
router.get('/', function(req, res, next) {
console.log(req.session);
var testArray;
var errorMessages = req.flash('user-error');
if (errorMessages.length === 0)
testArray = ['errorMessages is empty'];
else
testArray = ['errorMessages contains a message now'];
console.log(errorMessages);
console.log(testArray);
res.render('index', {
message: errorMessages,
tester: testArray,
...other irrelevant vars being passed...
});
});
router.post('/add', function(req, res, next) {
var ajaxData = req.body;
console.log(ajaxData);
User.findOne({name: ajaxData.name}, function(err, user) {
if (err) return console.error(err);
// if User DNE already in DB
if (user === null) {
...new user created and saved here...
}
/*where the important stuff begins*/
else {
console.log("flash message set");
req.flash('user-error', "A user with that name already exists!");
}
// redirect to index
res.redirect('/');
});
});
In my Jade template, I'm again logging errorMessages and testArray to make sure everything is passed to the file correctly (it is) then showing the variables.
index.jade
-console.log(message);
-console.log(tester);
.error-box Error: #{message}
.error-box Error: #{tester}
Initially loading the page, I will get the following HTML output:
<div class="error-box">Error: </div>
<div class="error-box">Error: errorMessages is empty</div>
No surprises here. But when I submit the form with data that sets the error flash message, I get the updated logs from router.get('/') and index.jade with both the correct errorMessages and testArray variables. However my HTML output remains the same:
<div class="error-box">Error: </div>
<div class="error-box">Error: errorMessages is empty</div>
Clearly the variables being passed to Jade are being updated correctly, but it appears that Jade is simply not updating the HTML. With my somewhat limited knowledge of how connect-flash and Jade work, this would lead me to believe that this is a session related issue, however my code in app.js appears to be setup correctly...
var session = require('express-session');
var flash = require('connect-flash');
app.use(session({
secret: 'secret',
cookie: { maxAge: 60000 },
resave: false,
saveUninitialized: false
}));
app.use(flash());
I am relatively new to Express.js, so I feel like there might be something small I am overlooking or don't understand, but I've tried to be as detailed as possible so I'm hoping someone can help me out here!
After more careful inspection, I found that what was really causing the issue was that res.redirect('/') was not running, as I was attempting to use AJAX on the client side to call router.post('/add').
I solved this by simply removing my AJAX request, then going back into my HTML and changing my form's attributes (the form whose data I was sending via AJAX) to include method="POST" and action="/add". This is the proper way to make a SERVER SIDE call to my router.post('/add').
I found that someone was having the same problem here, and this question initially led me to look into the AJAX/Client Side vs. Server Side issue. I found the latter question in a comment from #herbyme on this post.

Ajax call locally in jQueryMobile and Phonegap, JSON objects

I have very simple jQueryMobile application. I want to submit a form and to call ajax. On my desktop PC this works fine and looks like this:
application on my PC
When i press the button "Save" the text below appers. The HTML code for the interface is in the script accountAdd.html. At my PC It works as expected, but i need this app for my mobile device. Here is the screenshot from my device when i try to do the same thing that is showed at the first figure.
application on my mobile device
So here is the part of the script that calls ajax.
accountAdd.html
<script>
$( document ).ready(function() {
$(document).on('submit', '#formDetails', function() {
var theName = $("#accountName").val();
if($('#accountName').val().length > 0) {
$.ajax({
url: 'accountAdd.php',
data: $('#formDetails').serialize(),
type: 'post',
dataType: 'json',
timeout: 5000,
success: function (result, status) {
$("#resultLog").html("accountName: " + result.accountName);
},
error: function (request,error) {
alert('Network error has occurred please try again! Error: ' + error);
}
});
} else {
alert('Please fill all necessary fields');
}
return false;
});
});
</script>
.
.
.
HTML code
Here is my other script that contains code that is executed in back-end.
accountAdd.php
<?php
header('Access-Control-Allow-Origin: *');
$return['accountName'] = $_POST['accountName'];
$return['accountType'] = $_POST['accountType'];
$return['accountBalance'] = $_POST['accountBalance'];
$return['accountDate'] = $_POST['accountDate'];
echo json_encode($return);
?>
So the ajax call on my mobile device is not working as expected and as you can see at the second figure is giving parseerror. The code is completely the same at both devices. I'am converting the scripts with phonegap. I think that the problem is related with JSON objects (I think that ajax call in phonegap need to pass JSON obejects but I'm not sure). I need help, how to modify the code, so that can work at the PC and at my mobile device at the same time.
Ok, you have <access origin="*"/> so it is not a CORS issue.
I think maybe your problem is that you do not set the datatype to json in your php but expect it in the javascript side. Try adding the following line in your php file :
header('Content-Type: application/json');
Edit
I see the url to your php uses local path (should have noticed earlier but didn't know if you removed the server address on purpose), so it seems you put the .php files in the phonegap app.
That is not how it works. Either you need to do things locally and you do it in javascript, or you want to communicate with a server and you
do not put any php page in the www folder of your local page
provide the url of your server to each ajax calls.
Make sure your config.xml file is in the same folder as your index.html file and then use the (Or whatever domain you are on)

Variable code in AJAX coding

i found a code fore an ajax tutorial,and am not familiar with some part of the code there
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
document.myForm.time.value = ajaxRequest.responseText;
}
}
ajaxRequest.open("GET", "pay.php", true);
ajaxRequest.send(null);
can someone please tell me what the above code means,are there any variables,etc?
I am aware that pay.php is the php file it reffers to,but what does the first three line of coding mean?
The XMLHttpRequest object has a property called readyState. This is where the status of your server's response is stored. The response can be processing, downloading or completed. Each time the readyState changes then our onreadystatechange function executes.
When the property readyState is 4 that means the response is complete and you can get your data.
The function refers to a textbox named time,in a form named myform"The value is taken from the code in pay.php file.

Codeigniter not detecting form on jQuery send

I'm going a little crazy here as I'm at a real loss for words what is happening. After a lot of digging around, I believe I am doing everything as should be.
Situation
I'm trying to send a user creation form to the server via AJAX and codeIgniter fails to even get past this part
if($this->input->post('blnAjax')) { // do something }
I have successfully incorporated the AJAX side of things in to the client as it fetches content from the server with very little problem. Here are some of the details involved in the call:
Ajax code
The ajax code is part of a much larger framework beyond the scope of this question but in terms of the actual call function, the event has event.preventDefault(); event.stopImmediatePropagation(); to stop it running off. The URL is reachable and the post values have been serialized with request type set to POST
requestpage: function(){
var strURL = params.strBaseURL + params.strRequestURL;
$.ajax({
type: params.strRequestMethod,
url: strURL,
data: params.strRequestParameters,
dataType: 'json',
success: function(json) {
methods.postrequestprocedure(json);
}
});
},
Ajax request
Everything runs smoothly on the client making the XMLHttpRequest with json as expected return. I don't even get to this point when the form has been submitted however. Codeigniter will never think the form has been set if using AJAX
Parameters application/x-www-form-urlencoded
blnAjax 1
user_login_name[] fred
user_login_name[] ted
user_name[] Fred Flintstone
user_name[] Ted bear
usergroup_id[] 16
usergroup_id[] 16
Controller
On the controller, with regard to the action, I have included alall code up to the point of fail. Please note that I have tested the other aspects of the code and they run fine
public function user_add() {
/* Include extra script files needed for form handling */
$this->view['aryScript'][] = 'jquery.validate.min';
$this->view['aryScript'][] = 'jquery.validate.additional-methods';
/* Include extra CSS files */
$this->view['aryCSS'][] = 'form';
/* First check if the user has correct access rights */
if($this->view['intAccessLevel'] < INT_SUPER_USER_ACCESS_LEVEL) {
$aryResponse['notifications'][] = array('strType' => 'permanent',
'strMessage' => 'Denied!');
}
/* Import extra libraries and helpers */
$this->load->library(array('PasswordHash'));
$this->load->model('UserAdminModel');
$this->view['strTitle'] = 'Add User';
$this->view['aryButtons']['user_add_another'] = array(
'strDisplay' => $this->lang->line('user_add_another')
'strURL' => '#',
'strID' => 'user_add_another',
'aryData' => array('action' => 'form-clone')
);
if($this->input->post('blnAjax')) {
echo 'Big sigh of relief';
Thank you kindly for taking the time to read my problem
The answer is never as simple as it seems! My client is using a CodeIgniter mod that rewrites the URI and thus dumping the data passed from the ajax query. It hadn't been a problem when performing gets and "real" POST queries.
So if you are ever using Wiredesignz - Language Identifier beware that it can affect your queries
How I fixed it, I use a custom page controller but the theory is the same:
Be sure that you have $this->config->item('language_abbr'); available to your javascript functions maybe through a constant or echo it directly in to the javascript if on the same page
Modify the URL before sending it with something similar to params.strBaseURL + params.strLanguage + '/' + params.strRequestURL;
You should now find things work just fine. I hope this helps and noone else has to spend a mini eternity to find this out

Resources