Redirect parent page from AJAX loaded tab - php

SO I have a php function for redirecting
public function redirect($url, $permanent=false, $statusCode=303) {
if(!headers_sent()) {
header('location: '.$url, $permanent, $statusCode);
} else {
echo "<script>location.href='$url'</script>";
}
exit(0);
}
It's done me wonders so far, but Lets say that I am loading a tab via AJAX, which requires a user to be logged in. So ideally when the tab loads and it detects the user isn't logged in it redirects them to the index page. However, instead, the redirected page (http://localhost/something/index.php in my case) just loads inside the tab which makes sense, but is obviously not what I want to happen :)
However, is there a php solution to do this? Or should I just have a JavaScript redirect function at the root level that I call from the loaded AJAX tab if the user is not logged in?
Edit: Sorry. to clarify what I mean by tab, it's just HTML loaded into a DIV tag via AJAX

Your question isn't totally clear in regards to what you mean by "tab"
Maybe it would work for you to use
top.location.href='$url'

you can try
php function
public function redirect($url, $permanent=false, $statusCode=303) {
if($_SERVER['HTTP_X_REQUESTED_WITH'] === "XMLHttpRequest"){
die("AjaxRequest");
}
else{
if(!headers_sent()) {
header('location: '.$url, $permanent, $statusCode);
} else {
echo "<script>location.href='$url'</script>";
}
exit(0);
}
}
Javascript function
function ajaxresponse()
{
var response = //your ajax request response
if(response == 'AjaxRequest')
{
location.reload();
}
}
Explaination:
First Check in php whether it is ajax request or not.
so for redirection, send response from php as ajax session so that u can check out this response in javascript for which redirection will not take place.
after detecting this response in javascript you can redirect to index page from your javascript function.
Hope this helps

Related

PHP die() shows brief white screen

I'm using a redirect function to redirect visitors to a certain page when they don't have access to the current page. The function is as follows:
$user->redirect('www.google.com');
die();
The redirect function links to:
public function redirect($url="",$time=0) {
header("Refresh: $time; url=$url");
}
Whenever you get redirected you briefly see a white page followed by the page you get redirected to. I'm assuming the white page is caused by die().
I don't like it and I really want to get rid of this.
The problem is not related to the die() call, but that you are sending the wrong header to handle a redirection.
Instad of doing
public function redirect($url="",$time=0) {
header("Refresh: $time; url=$url");
}
do:
public function redirect($url) {
header("Location: $url", true);
}
Or even:
public function redirect($url, $temporal = false) {
header("Location: $url", true, $temporal ? 302 : 301);
}
With this you are sending a status code "301" or "302", to indicate that the redirection is either temporal, or a permanent. Defaulting to a permanent redirect, since temporals are very rarely useful (although in your case, being a redirection because of permissions, a temporary redirection might be in order)
(I also removed the default value for $url, because it doesn't make much sense to redirect to an empty url)
Instead of using a 'Refresh:' header, you can just use 'Location:'. This way, the page does not have to be refreshed and will probably result in your desired behaviour.
public function redirect($url="/") {
header("Location: $url");
}
edit: added default $url '/' so that if no url was given it redirects to homepage
I'm disapointed to the prev. posts. It is about the die() !
When sending a header the browser takes a little time to take action. Between this time the php process then calls die() before you are redirected. This is asyc. Location and Redirect
So it shows you a black page and then you/visitors get redirected.
Good: setting die() to end the process to avoid futher actions inside your program
Bad: The blank page first.
This is depending on your enviroment of your browser! E.g: a very slow workstation will show you this behavior and you have to care about. Imagin the browser does know about header redirections (Today it (mostly) doesnt exists anymore)
To give the browser a change to take action, use this:
function someaction() {
// ...
$user->redirect('www.google.com');
// which give the time for the browser
// without further execution of your code
return;
}
In this case the visitor stays as long on the current page until the browser knows about headers or the cpu is slow but will take action when it is able to take action.

How to force page reload in zend php

Actually I am using ajax call and my code sample is here.. Please don't mind the syntax
$.ajax(
url: "mysite/action1",
success: function(resp) {
$("#divId").html(resp);
});
Like this I am loading the response text into one div tag. Now my problem is in zend controller I am trying to check for one condition like if session expired means redirecting to login page or else sending the response html code for that action.
public function action1Action() {
$login = new Zend_Session_Namespace('login');
if (isset($login->employee_id)) {
echo $html;
} else{
$this->view->headMeta()->appendHttpEquiv('refresh','1');
//$this->_helper->redirector->gotoUrl($this->view->baseUrl());
//$this->_helper->redirector('index', 'index');
}
}
I tried these three ways
$this->view->headMeta()->appendHttpEquiv('refresh','1'); -- Nothing happening
$this->_helper->redirector->gotoUrl($this->view->baseUrl()); and $this->_helper->redirector('index', 'index'); -- loads login page within the div tag (as it is taking as the ajax response)
I just want to reload the page. Just like triggering the browser refresh button to achieve what I want.. Please suggest any idea to solve my problem..
Note : I want to page reload from server side rather than checking in ajax response.. Is there a way to do it?
As you mentioned, you are trying to trigger "browser refresh", which is a frontend event. So I don't there you can do that in the backend.
It can be achieved using simple js code
window.location.reload();
When session expires just throw exception with proper HTTP code 401.
throw new Zend_Controller_Action_Exception('User not authorized', 401);
Then you can write global callback function for ajaxError and reload page or redirect user where you want.
$( document ).ajaxError(function(event, jqxhr) {
if (jqxhr.status === 401) {
window.location = '/'; // Use same base url here
}
});
You can take this one step further and write ACL plugin on preDispatch function to throw this exception. Then just ajdust little bit ErrorController so users are also redirected to login page and you will have consistent behavior for all requests, not only for XHR requests.

PHP/js session expiration loads whole page in dv

I have a password protected website--imagine something like linkedin-- where if the session expires you are prompted to log in again.
Some pages have ajax calls, however, that load content from the server into divs.
If you come back to the open div after the session expires and try to enter something, the php on the other end does a redirect within the div, and basically loads the whole login page inside the div. This creates a page within a page, an obvious error that tells the user, the site is not working properly.
Instead of the login page appearing inside the open div, I would like the div to close and the whole page redirect to the login. I am having trouble accomplishing this, however.
Right now I am doing the password protection with an include that checks for session and either allows you to continue or bumps you out to the login page.
If ($_SESSION['login'] != '1') {
header("Location: relogin.php"); }
I have this include in the scripts triggered by ajax calls to fill divs so users cannot bypass security. It is a catchall include that also holds some global variables, functions and so forth.
Can I add code that detects if call is coming from ajax or something so as not to do redirect and instead give message to login. Or ideally, close div and redirect whole page?
Because it is a large site, I would like to find one block of code that could go into the global include.
Would appreciate any suggestions.
You will need to do the redirect on the JS side.
Let's go over the PHP side first. You want to give your AJAX handlers a clear, unambiguous, stateful response: "sorry, you're not authorized". Let's borrow from REST a bit right?
Top of each of your AJAX calls:
<?php if (!YouAreLoggedIn()) {
header($_SERVER['SERVER_PROTOCOL']." 403 Forbidden");
exit(); ?>
This will throw the visitor a 403 error, and will kill the script. 403 errors in jQuery count as a XHR error, so you can map it independently of everything else.
Your typical AJAX call then becomes:
$.ajax({
url: "your.url.here.php",
type: "POST",
success: function(d) { YourSuccessCallHere(); },
error: function() { window.location.href='your.redirect.here.php'; }
});
This is the cleanest way to do it.
You could differentiate the two different calls by User-Agent or other header fields.
Use setRequestHeader() as described in links below:
JQuery Ajax Request: Change User-Agent
http://www.w3.org/TR/2007/WD-XMLHttpRequest-20070618/#dfn-setrequestheader
You could add a GET variable to the request URL whenever you're calling it via Ajax:
myurl.php?ajax=Y
Then on myurl.php, check to see if it's an ajax call:
if(!isset($_SESSION['login']) || $_SESSION['login'] != '1') {
if(isset($_GET['ajax'])){
echo json_encode("Please login!");
exit;
}
else{
header("Location: relogin.php");
exit;
}
}
Use the following header to check if the request was an AJAX request:
X-Requested-With: XMLHttpRequest
read the header in php using:
$_SERVER['HTTP_X_REQUESTED_WITH'];

Handling php redirect in ajax call when codeigniter/tank auth session timeout reached

Hey all I have a javascript function within a codeigniter view that retrieves some information from a codeigniter controller function that is acting strangely when the timeout for a user's session is reached. Within the called php function I have a statement that looks like this:
if (!$this->tank_auth->is_logged_in()) {
redirect(site_url('login'));}
This redirects them to my login page if they are not logged in. However in the javascript function I take the response text and set the contents of a div equal to it.
xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "mycontroller/myfunction/", false);
xmlhttp.send();
document.getElementById("mydiv").innerHTML=xmlhttp.responseText;
If the user is logged out when they call this function it will return the login page's responseText and insert it into the div instead of redirecting to the login page. This looks terrible. How can I stop it from doing this if the user session times out while looking at this page? I cannot change the timeout limit because other applications rely upon it.
Really this is not a codeigniter or tank_auth problem at all, simply how to redirect from a php function that is being called in an ajax request instead when I am originally using that function to generate a string for the responseText.
You need to parse the response and determine whether it is the type of response you're expecting. If you're expecting under a certain number of characters, you can check length, but that might not be as reliable as checking for specific dom objects or strings.
You could do, for example:
if(xmlhttp.responseText.length < 200) {
document.getElementById("mydiv").innerHTML=xmlhttp.responseText;
} else {
window.location.href = 'some url';
}
Another alternative would be to use CodeIgniter's AJAX response check to do something else instead of loading the view (or load a different view):
if ($this->input->is_ajax_request())
{
// do something else
}
else
{
// do what you were doing before
}
Hope this helps! I would shy away from doing the PHP/CI method because it sounds like you would be adding exceptions everywhere in your code which would not be pretty. It's totally up to you, though.
if you know your login design well. you can handle your response like this.
success: function (response) {
if(result.substring(0, 15) == '<!DOCTYPE html>') //Your login's HTML initials.
window.location = site_url_path + 'login'; //session timeout redirection.
//your normal functionality
}
It will be helpful when you have written redirection in a construct of your controller.

PHP- Ajax and Redirect

i have a jquery Ajax request happening on a page. On php side i am checking if the session is active and doing something. If the session is not active i want to redirect the user to another page in php(header redirect). how do i do it.
I know how to achieve it in javascript(i.e if session_fail then change window.location but is there something that i can do in php/cakephp
Redirects only say "The data you requested can be found here".
HTTP provides no way to say "Even though you requested a resource to go inside a page, you should should leave that page and go somewhere else".
You need to return a response that your JavaScript understands to mean "Go to a different location" and process it in your own code.
If I understand what you want to happen then this is how I'm implementing it. It's in Prototype instead of jQuery but it shouldn't take you long to translate:
new Ajax.Request('process.php', {
on401: function(response) {
var redirect = response.getHeader('Location');
document.location = redirect;
}
});
In your PHP, output the following if the session is inactive:
header('Location: http://example.com/login.php', true, 401);
exit;
This is what you would want in your php IF THIS WERE A REGULAR REQUEST, NOT AN AJAX
if (isset($_SESSION)) doSomething();
else header("Location: otherUrl");
Since this is an Ajax call, you are not passing control to the php, but just trying to get a response that (likely) fills a particular section of your page. You do not mention what jQuery ajax function you use, but it matters. I would imagine you are using either $.get() or $(element).load() ??
Without knowing the particulars, this is my best suggestion for you.
Ajax call: $.get(url, callbackFunc);
php:
if(isset($_SESSION)) echoSomething() else echo("redirect");
callbackFunc:
function(data)
{ if (data == "redirect") window.location = otherUrl;
else
$("#desiredElement").html(data);
}

Categories