Cakephp - Proper way to return AJAX Success response? - ajax

I have been using the trick below to return success response with AJAX:
//In controller
echo 'success';
//In Javascript
if(response == 'success'){
//redirect
window.location.href = '/users/profile/';
}
It works fine on localhost. But in web server, I got the error below everytime I want to redirect the page after success:
Cannot modify header information - headers already sent by (output started at ...
So yeah, I know it is caused by the echo before redirecting.
So, Is there proper way to return the success response? No need to be a message, just true or false is enough.
[EDIT]
By using exit('success'), it works fine, but is this the best way?
Thanks.

It is better to redirect from javascript.
//In controller
echo 'success'; exit;
//In Javascript
if(response == 'success'){
window.location = 'your-controller-action';
}
EDIT
You may have space before/after php Opening/Closing tags in controller and models. Remove all the closing tags from all controllers and models and any whitespace before opening tags. Then check the result.

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

Codeigniter controller detecting ajax file upload

I have set up my Codeigniter application so that I can upload files via Ajax. I followed this tutorial http://net.tutsplus.com/tutorials/javascript-ajax/how-to-upload-files-with-codeigniter-and-ajax/
My original form checked to see if an ajax request had been called, if not then I had the fallback CI form validation / error messages showing instead.
I checked this using - $this->input->is_ajax_request()
My code looked like this:
if($this->input->is_ajax_request()){
// process ajax form data
} else {
if($this->form_validation->run() == FALSE) {
$data['success'] = 0;
$data['errors'] = validation_errors();
} else {
$data['success'] = 1;
}
$this->load->view('form', $data);
}
After doing some investigation I discovered that I couldn't apply the same technique because it isn't actually an ajax request, therefore I am not sure how I can use this approach. If anyone can point me in the right direction that would be great. I don't like it being totally dependent on ajax, I like having a fallback option. I noticed in the comments that someone has set up a CSFR cookie in their ajaxfileupload.js but to be honest I'm not too hot with js so I wouldn't know where to begin. Thanks in advance.
In your AJAX request along with everything else you could post key/value:
ajax : 1
Then in your controller:
if( $this->input->post('ajax') == 1 ) {
// process ajax form data
}
else
{
// form validation
}
Hope this helps.

how can I redirect in .jsp while working with Ajax

I am developing application using Ajax and jsp.
My index.jsp page has HTML code for Login and some Ajax code in javascript. Ajax will call my another CheckLogin.jsp page
CheckLogin.jsp page checks on server for valid username and password. It returns "success" if it's valid otherwise will return message stating "username or password is not valid."
Now, when username and passwrod is valid, instead of success, I want to redirect the page to "Home.jsp" what should I do?
I am new to jsp. I appreciate your help on this.
JSP code gets run once on the server before it goes to the client, so JSP/JSTL cannot do a redirect following the success or otherwise of an AJAX call (without a full page refresh - which obviates the use of AJAX). You should to do the redirect with Javascript:
if (success) {
var successUrl = "Home.jsp"; // might be a good idea to return this URL in the successful AJAX call
window.location.href = successUrl;
}
On successful AJAX call/validation, the browser window will reload with the new URL (effectively a redirect).
Since I don't see your code, you can integrate this somewhere inside your validation :
<%
pageContext.forward("logged.jsp");
%>
function Edit() {
var allVals = $('#NEWFORMCampaignID').val();
if (allVals > 0) {
window.location = '/SMS/PrepareSMS?id='+allVals;
}
else
alert("Invalid campaign to Edit")
}
In order to redirect using Button click and pass some parameters, you can call the Controller Path(#RequestMapping(value="/SMS/PrepareSMS")) and then handle it there..

How do you differentiate between an AJAX GET and an AJAX POST request in CakePHP?

In my CakePHP app for my login method I do some different things for when a user submits a form via AJAX calls using if ($this->request->is('ajax'))
However I also want to allow the login method to be shown in a modal for quick login which again is an ajax call. But how do I detect the difference between the AJAX GET to show the form and then AJAX POST to do the actual login?
See below I can detect native get and posts but for ajax how do I detect the difference in CakePHP??? As it seems I can only detect an ajax event and not the type :/
NATIVE:
GET = if ($this->request->is('get'))
POST = if ($this->request->is('post'))
AJAX:
GET = if ($this->request->is('ajax'))
POST = if ($this->request->is('ajax'))
Thanks
Solution:
if ($this->request->is('get'))
{
if ($this->request->is('ajax'))
{
echo json_encode('ajax get'); exit;
}
else {
echo 'Normal get'; exit;
}
}
if ($this->request->is('post'))
{
if ($this->request->is('ajax'))
{
echo json_encode('ajax post'); exit;
}
else {
echo 'Normal post'; exit;
}
}
Not sure if I understand the question, but if the problem is that the form data can come in either as a POST or GET, the solution is to check whether the POST data is there. If it is, use POST, otherwise take the data from GET. (Or other way around.)
If the function should do different things depending on whether the form has been sent as POST or GET, then simply make two different functions in the controller.

_remap ignoring IS_AJAX call?

This issue is very likely codeigniter specific.
I have a controller called redirect.php that redirects from and to views. This controller for the most part has one public _remap function that does all the redirecting with a case statement. Everything has been working great until I sent a $.POST from a view back to the controller. I want it to hit the _remap and look for the fact that the request is coming from AJAX then do it’s case.
I have a IS_AJAX constant I’m checking against.
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
but whenever I hit the page it’s always remapping to the default and sending my request to that page where it’s basically returning me that pages data back when I’m echoing and alerting the data to and fro.
Any insights?
for reference,
redirect.php (there is more code to define variables and 2 more cases but it's not hitting those, it's hitting 'index' / default)
public function _remap($method)
{
switch ($method) {
case $method == 'index':
$this->load->view('main');
break;
case $method == 'IS_AJAX':
var_dump($_POST);
break;
default:
$this->load->view('main');
}
}
tweetview.php (view loaded by redirect controller in another case within redirect.php, json_tweets send is a JSON variable)
//jquery
$.post("http://localhost/2fb/index.php/redirect", {'json_tweets': json_tweets},
function(data) {
alert(data);
});
Instead of doing all this you can rely on $this->input->is_ajax_request() from http://codeigniter.com/user_guide/libraries/input.html. If you are not interested in loading a library, here is somewhat similar code I have in production for last two years at least.
$ajax = ($_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest')? true : false;
Look at the string, its XMLHttpRequest and the jQuery is the frontend JS toolkit
Just to add more, I usually have one entry point for Ajax calls, so obviously I have one controller for ajax and route all my calls through it. Why would I do that? Simple reason, I make sure all my forms submit to a simple non ajax form handler at server if JS is turned off. If JS is on, jQuery/prototype/YUI takes control and sends data to my ajax controller. The end handler which actually does all the validation/verification/db interaction is common code.
case $method == 'IS_AJAX':
Your $method is not IS_AJAX with this url:
http://localhost/2fb/index.php/redirect
This would bring you to the redirect controller without a method (will default to "index"). You literally would need:
http://localhost/2fb/index.php/redirect/IS_AJAX
...to step into that case. You seem to be confusing your constant IS_AJAX with the method requested, which you seem to be using correctly when checking for index (although this is the same as the default case, so it's redundant).
$method, or whatever you name the first parameter in _remap(), will always be the routed controller function that is called.
EDIT: I failed to mention this earlier, but the switch block evaluates the expression you pass to it, so there is no need to do the comparison manually. Example:
switch ($method) {
// case $method === 'index':
case 'index':
$this->load->view('main');
break;
}
try this ,
$.ajax({
type: "POST",
url: "your function url goes here",
data: data,
success: function(html){
window.location = 'redirect url goes here';
}
});

Resources