I have a logout function that looks like this.
if ($_GET["argument"]=='logOut'){
if(session_id() == '') {
session_start();
}
session_unset();
session_destroy();
$host = $_SERVER['HTTP_HOST'];
$extra = 'index.php';
header("Location: http://$host/$extra");
exit;
}
My problem is that, If I inspect the page and look at the Network preview and response, it looks 'fine'.
There are two php files listed that was processed.
http://localhost:5000/inc/mainScripts.php?argument=logOut
which is where the function is located.
and http://localhost:5000/index.php
Which is where i would like to be redirected.
The Response tab in the Network of the inspect page area in chrome
contains the full login html page login.php but in the browser it remains in the same place. Like the header command has never been called.
What Am I doing wrong?
HTML AJAX call to this function:
$("#logout_btn").click(function() {
$.ajax({
url: './inc/mainScripts.php?argument=logOut'
})
});
SOLUTION
AJAX
$("#logout_btn").click(function() {
$.ajax({
url: './inc/mainScripts.php?argument=logOut',
success: function(data){
window.location.href = data;
}
});
});
PHP
if ($_GET["argument"]=='logOut'){
if(session_id() == '') {
session_start();
}
session_unset();
session_destroy();
$host = $_SERVER['HTTP_HOST'];
$link = "http://$host/index.php";
echo $link;
}
Try this instead.
if( isset($_GET['argument']) && $_GET['argument'] == 'logOut' && !empty( session_id() ) ) {
session_destroy();
header("Location: http://" . $_SERVER['HTTP_HOST'] . "/index.php");
exit;
}
Edit: If you're using AJAX, it'd be easier to send the url from your php script back to your javascript and redirect from there.
You are probably running into the same common problem that many people run into when people first start to program in PHP.
Calls to header() only works when there are NO previous HTML output generated. If there are any HTML output generated, even just a single space, calls to header() will fail. To get around this problem, use functions such as ob_start() and ob_end_flush().
Related
I have encounter 1 problem when sending message to other php file and show success notification message with sweet alert. Initially, the program is expect to go to other php file(index.php) with message sending with url and run the php code in index.php(The page if there is no error found in login function.php).Login function php is where all the function for checking for login.php. Index.php is where user successful login into the system.
In login function.php i have this code
header("Location: " .$path."/order/index.php?page=1&login_status=success");
In bottom part of index.php, i have included php code below.
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<?php
if(isset($_GET['login_status']) && $_GET['login_status'] == 'success'){
echo "<script>
Swal.fire({
icon: 'success',
title: 'Welcome to MyCommerse',
})
</script>";
echo "<script>
history.replaceState(null, '', location.href.split('&')[0]);
</script>";
}
?>
When i run debugging with PHP Debug in visual studio code, the program stop at header("Location: " .$path."/order/index.php?page=1&login_status=success");. It does not run the coding in index.php.
As per your explanation, File2(index.php) can not cause any issue on File1(function.php) as File1(function.php) is loading first and successfully executing code.
Ideally, code should have
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$page = "order/index.php?page=1&login_status=success";
header("Location: http://{$host}{$uri}/$page");
exit; // add exit here to terminate the script execution
double check your $path variable
I'm working with Slim Framework and I would like to redirect the user to the login page if the user has lost his session but I'm always getting a SyntaxError : Unexpected token < at position 0.
My session validation code in php is this:
private function _validaSessao() {
$user = $this->userData['IdUser'];
if(null === $user || trim($user) == '') {
header("Location: http://192.168.0.9/", true, 301);
die();
}
}
I've tried that and all the following:
header('refresh:5;url=http://192.168.0.9/');
echo '<script>window.location.href = "http://192.168.0.9/";</script>';
return('<script>window.location.href = "http://192.168.0.9/";</script>');
echo json_encode('<meta HTTP-EQUIV="REFRESH" content="0; url=http://192.168.0.9/">');
I've tried them all and I'm always getting
200 ---- SyntaxError: Unexpected token < in JSON at position 0
The only piece of code that worked for me was:
echo json_encode(array(
'SemSessao' => true
));
But the above code makes me checking on every single call on JavaScript and I would like a solution that PHP will redirect me. This way I wouldn't need to keep checking on every single JS call (which are a lot) and each time a php object was instanciated it would check for session and redirect the user without the use of JS.
Update 1 - Include JS code (lovely downvotes everywhere :D)
getDadosPlaneamento: function() {
var req = {Rota: '/planeamento/getDados/AUTO'};
var dfd = $.Deferred();
$.when(App.gajax(req)).done(function(d) {
On.Planeamentos = d.Planeamentos;
dfd.resolve();
});
return dfd.promise();
},
The above code is what refers to my php route and then:
$onapp->get('/planeamento/getDados/:tipo/', function($tipo) {
if ($tipo == 'AUTO') {
$P = new MongoApi\Planeamento();
$ret = array(
$P->getAllMongo();
);
}
echo json_encode($ret);
});
And when I do $P = new MongoApi\Planeamento(); I check if the user has a valid session on the constructor using _validaSessao();
The server cannot redirect a client from an AJAX call. The AJAX call is a background HTTP request. Whether that HTTP requests gets redirected or not is irrelevant to the browser. The browser will return the request response to the AJAX client, and if that response is "your request has been redirected" then that's that. Again, a redirect doesn't redirect "the browser", it redirects the HTTP request. Or more precisely speaking, it tells the HTTP client that it should retry its request somewhere else; nothing more.
If your AJAX requests can fail due to a session timeout and whenever that happens you want to present the user with a login page, you will have to do that client side. In order to not repeat that same code every time, you make a function/object/service out of that. E.g. something along the lines of:
function makeAJAXRequest(url, data) {
return fetch(url)
.then(response => {
if (response.status == 403) {
window.location = '/login';
throw new Error('Forbidden');
} else {
return response;
}
});
}
Here the server is expected to respond with a 403 Forbidden status code for unauthorised requests. If you make all your AJAX requests through this function, it will automatically handle that case by redirecting to the login page.
Remeber that header() must be called before any output is generated. you can use ob_start() and op_end_flush() to avoid output previous to your header.
ob_start ();
header ("Location: http://192.168.0.9/", true, 301);
ob_end_flush ();
I'm starting with PHP, so I have no idea what's going wrong. I'm trying to update some value in my $_SESSION var using a function, but is not working.
First of all, I started the session and set a default value to the session if it is "undefined" in my header.php:
<?php
session_start();
if (!isset($_SESSION["locale"])) {
$_SESSION["locale"] = 'pt_BR';
}
?>
Then I have some ajax which calls my PHP function.
$('#change_locale_br').click(function() {
$.ajax({
type: "POST",
url: "i18n/i18n_functions.php",
data: { action: "changelocale", new_locale: "pt_BR" },
success: function() {
}
});
});
After in the php file, I have the following code:
<?php
function changelocale($l) {
$_SESSION["locale"] = $l;
}
if(isset($_POST['action']) && $_POST['action'] == 'changelocale'){
$l = $_POST['new_locale'];
changelocale($l);
}
?>
So the changelocale function is being called with the different values (pt_BR, es and etc), but after called it doesn't really change the $_SESSION["locale"] value.
I made a lot of research and NONE of the suggestions made here or in the PHP documentation page worked. Does someone knows what could be done in this case?
Thanks in advance.
You need to include session_start() at the top of your page, which you intend to set or access $_SESSION information.
Here is the solution: I called session_write_close(); (which is used to assure session data will be "unlocked", since php doesn't allow concurrent writes) right after setting the default values for the session in my header.php:
<?php
ini_set('session.cookie_domain', 'localhost');
if(!isset($_SESSION)) session_start();
if (!isset($_SESSION["locale"])) {
$_SESSION["locale"] = 'pt_BR';
}
session_write_close();
?>
Then in my changelocale.php I called the session_start() and at the end called the session_write_close(). It's like this now:
<?php
if(!isset($_SESSION)) session_start();
function changelocale($new_locale) {
$_SESSION["locale"] = $new_locale;
}
if(isset($_POST['action']) && $_POST['action'] == 'changelocale'){
$l = $_POST['new_locale'];
changelocale($l);
}
session_write_close();
?>
I have a custom framework and I detect if a request is an ajax in my Request file. In my basecontroller I check if user is logged in:
If user is not logged in:
1. if request is ajax - force JS redirect from PHP (unable to do)
2. if request is not ajax - PHP redirect (header, works)
I cant get number 1 to work.
Here is my redirect code:
//User::Redirect
public function redirect($url = SITE_URL, $isAjax = false) {
if ($isAjax === true) {
//its ajax call, echo js redirect
echo '<script>window.location = ' . $url . ';</script>';
} else {
header("Location: {$url}");
}
exit;
}
Code for login check:
//Basecontroller::__construct
if ( ! $this->user->isLoggedIn()) {
//redirect to login page
$this->user->redirect('/login', $request->ajax());
exit;
}
But instead of redirecting on ajax calls it just outputs <script>window.location = URL</script>
NOTE:
I know i could add check on each of my AJAX call to do redirect from there but Im trying to avoid that and let my PHP script detect in base controller and redirect rather than me adding check to all of my AJAX calls (alot).
Your Javascript redirect needs script tags. Try this:
public function redirect($url = SITE_URL, $isAjax = false) {
if ($isAjax === true) {
//its ajax call, echo js redirect
echo '<script>window.location = ' . $url . ';</script>';
} else {
header("Location: {$url}");
}
exit;
}
In terms of handling this within your ajax, assuming jQuery
$.ajax(
{
type: "POST",
url: url,
data: postParams,
success: function(data)
{
//do something with success response
},
error : function(httpObj, txtStatus)
{
if(httpObj.status == 401)
{//redirect to login
var loginUrl = '/login';
document.location.href = loginUrl;
}
else if(httpObj.status == ...) //etc
{//do something
}
else
{
alert("Ajax\n Error: " + txtStatus + "\n HTTP Status: " + httpObj.status);
}
}
How is the client supposed to know that is javascript?
Try encasing it with script tags
i.e.
<html>
<script>
window.location = 'testpage.html'
</script>
</html>
This code works for me. If an ajax call finds the user is not logged in (eg: the user has left their browser open and their session has expired) the PHP will echo out the refresh code either as JS or a meta tag to the browser to force a refresh of the whole page.
$url = '/index.php';
echo '<script type="text/javascript">';
echo 'window.location.href="'.$url.'";';
echo '</script>';
echo '<noscript>';
echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
echo '</noscript>';
I have a simple registration form and the new comers will be registered with an ajax function. There I create a $_SESSION['is_logged'] when the registration is finished.
On var_dumb I get that the var is set. But when redirect on another page it is empty (I have included already the session_start() on the both pages...
I have read somewhere in the net that:
"Sessions are ONLY written on a page load/refresh".
Is this the case, or I have to look for some other issues within my code.
the ajax:
$.ajax({
url:"../controllers/register.php",
type:"POST",
data:res,
success: function(responce){
if (responce==1) {
$('#msg').addClass('msg-warning');
$("#form").css('display',"none");
$('#msg').append("<p>It seems that you have already submited the form. Click to "+
" <a href='login.php'>log-in</a> or to <a href='register.php'>register</a>.</p>");
}
else if (responce==2) {
$('#msg').addClass('msg-warning');
$("#form").css('display',"none");
$('#msg').append("<p>You have successfully created account. Click to "+
" <a href='start.php'>welcome</a> to start your .</p>");
$('.menu').append("<li><a href='logout.php'>Log out</a></li>")
}
else{
$('#msg').text(responce);
}
},
error: function(){
$('#msg').text("Opss, try again");
}
});
the register.php file:
if (isset($_SESSION['submited'])) {
echo 1;
exit;
}
include_once('../models/functions.php');
// Give the post parametters to another var
$arr=$_POST;
// function for uploading
$reg = registerMe($arr);
if ($reg === true) {
$_SESSION['submited']=1;
$_SESSION['is_logged']=1
echo(2);
}
else{
echo($reg);
}
exit;
The session_start(); is included in the header of the first page where from the ajax is started.And the second page - where the $_SESSION['is_logged'] is lost, again the session_start(); is part of dc_header(); function. start.php:
<?php
dc_header("Речник|Регистрация");
if (!isset($_SESSION['is_logged'])) {
#header("location: ../views/login.php");
var_dump($_SESSION);
}
?>
add
session_start();
to the top of register.php
You need to specify session_start, so your server who was commanded to execute "register.php" (either from ajax, direct call, browser scripts, cron job or whatever possible you-name-it) will handle the execution and the setting of $_SESSION variables in reference to the connected clients session. Server won't guess by itself that this is an "ajax call from an already session_start page". You need to specify that whatever is done in register.php is done in the current client's session.