document.referrer gives an incorrect value - javascript

I use document.referrer to see if a user has added a new message on my application. The page where the messages are shown is called 'messages.php' and the script that handles adding messages is called 'add_message.php'.
I want to create an effect on the last added message, but only if the user has just added the message. To see if the last message was just added and wasn't there before, I need to see if the user's last visited page was 'add_message.php'.
This is the code I use to detect the last visited URL with an if statement to check if that's the case:
var prevURL = document.referrer;
var newMessageURL = 'add_message.php';
if(prevURL.indexOf(newMessageURL) > -1) {
alert(prevURL);
}
The problem is that when I add a message, the script 'add_message.php' is called (via form action), however, document.referrer returns 'messages.php' as the last visited page, but it should be 'add_message.php', because that's where I come back from when I add a new message.
How can I get document.referrer to return 'add_message.php' when I add a message?
In the 'add_message.php' I use
header('Location: ' . $_SERVER['HTTP_REFERER']);
Does this cause the issue?

Referrers are unreliable at best, especially as browsers come with the option to spoof or hide it completely. In this case, because it's a redirect, the "in-between" page doesn't get counted as the last page you visited.
That said, since you're using PHP, there's another way:
As part of your add_message.php file, add this:
// assuming you already have session_start() somewhere above
$_SESSION['just_added_a_message'] = true;
Then, where you have your JavaScript now, replace it with PHP:
<?php
if( !empty($_SESSION['just_added_a_message'])) {
?>
<script>alert("Ohai there!");</script>
<?php
unset($_SESSION['just_added_a_message']);
}
?>
I use this technique myself to show a confirmation "You sent a Personal Message to X" message when the user has been redirected back to their Inbox after sending.

Related

WordPress wp_redirect clearing $_SERVER['REQUEST_URI'] before I can read it

I need to redirect all traffic on my WordPress site to the homepage if not requested by AJAX, but I need to use the requested path after redirect.
I have redirection working via wp_redirect php and a template_redirect hook, however I can't read the REQUEST_URI to save it via cookie or header or anything.
As soon as wp_redirect is called it seemingly prevents me from ever reading the details of the request, pre redirect. Comment out the wp_redirect and it reads just fine.
Is there something I'm missing here, or a better way to go about it? I have a one page site that is loading content via AJAX.
add_action('template_redirect', 'pass_along_request_uri', 1);
function pass_along_request_uri() {
// $_SERVER['REQUEST_URI'] is the path as expected only if the future wp_redirect is not called...
}
add_action('template_redirect', 'redirect_to_homepage', 10);
function redirect_to_homepage() {
if (!is_front_page() && (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest')) {
wp_redirect(home_url(), 301);
exit;
}
}
EDIT;
Only had 2 functions for testing, since logging $_SERVER['REQUEST_URI'] wasn't making sense to me. Thinking if I put the log at priority 1, it should be logged BEFORE the redirect happens with the priority 10 function.
However it doesn't. Doesn't matter when or where it seems, calling wp_redirect seemingly clears the original request data.
function console_log($output, $with_script_tags = true) {
$js_code = 'console.log(' . json_encode($output, JSON_HEX_TAG) .
');';
if ($with_script_tags) {
$js_code = '<script>' . $js_code . '</script>';
}
echo $js_code;
}
console_log($_SERVER['REQUEST_URI']);
Logs say "/path/to/page" when not calling wp_redirect, once wp_redirect is in the chain it only spits out "/" (the redirected path).
I'm thinking it has something to do with how actions are queued up with add_action? I don't know WordPress well unfortunately.
Thanks!
Your mistake here was the way you are actually logging this.
The console.log(...) executes on the client side - but there it can't log while you are doing your redirect elsewhere (you can not send output for the browser to interpret, like your script element, and redirect at the same time.)
What you are seeing is the result of that same logging code, executed via the request after your redirect.
Easiest way to achieve what you want, would probably be to stick the REQUEST_URI value into a session. You might have to start one then for that purpose, because WP does not use a "traditional" session by default.

JavaScript alert window after php script executed

here is may delete script - klient_usuwanie_script.php - It's working very well. BUT I would like it to present JavaScript alert when a record is deleted. So after the script deletes record it is a window with records shown - klient_usuwanie.php But I would like it to be this window with records but also with an alert saying "record deleted"
<?php
$sql = "DELETE FROM Klienci WHERE id= :del_klient";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
'del_klient' => $_GET['id']
));
header('Location:klient_usuwanie.php?msg='.urlencode($msg).'');
?>
So to clear it up. I have a page where I see records to delete - klient_usuwanie.php with a button "delete". When I press delete the script klient_usuwanie_script.php (which is included above) deletes a record. After that it redirects to the page klient_usuwanie.php and I can see other records and I can delete them. BUT after I delete a record I would like an alert window which says "Record deleted" that's all.
When I comment out
header('Location:klient_usuwanie.php?msg='.urlencode($msg).'');
and put
echo .$stmt->rowCount();
Than it shows me that one record was deleted but I would like it to be in an alert window and ideally alert to be shown on a redirected page.
You can redirect with query string like this:
header('Location:klient_usuwanie.php?msg='.urlencode($msg).'&deleted=true');
And in klient_usuwanie.php, parse the query param and show alert with javascript like the following:
window.onload = function() {
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get("deleted") === "true") {
alert("Record deleted");
}
}
Add to header('Location:klient_usuwanie.php?msg='.urlencode($msg).'');
header('Location:klient_usuwanie.php?msg='.urlencode($msg).'&skasowane=tak');
In the klient_usuwanie.php add someting like this:
if($_GET['skasowane']=="tak"){echo "<script>alert(\"I am an alert box!\");</script>";}
echo '<script type="text/javascript" language="Javascript">alert("Record Deleted Thats all")
</script>';
Suggestion for modern approach:
Disclaimer: This answer is more related to the intention than the exact request.
Why? Doing a full page reload for this sort of request is an outdated practice.
Nowadays, you'd more likely rely on AJAX calls for this sort of scenario.
A delete endpoint would take in a request with the ID and respond the correct HTTP code to indicate if operation was successful.
Restful HTTP endpoints can of course be written in PHP to respond with data instead of HTML.
Check out Swagger with good endpoint examples: https://editor.swagger.io
In your front-end, you could then implement the necessary JavaScript code to execute the AJAX request and manipulate the DOM as necessary.
Though many would use a Framework like Angular or React to standardise this workflow.
User Experience
This approach is far nicer to users as the browser does not need to reload the entire page again. As it only triggers one tiny HTTP request, it's much faster and the scroll location doesn't jump around either.
I've put up an example for the HTML on JS-Fiddle with jQuery to simplify the AJAX call:
https://jsfiddle.net/sny9hw73/3/
Example:
<div id="entry-<?=$id;?>" class="banner-message">
<p>My Entry with real request</p>
<button onClick="delete(<?=$id;?>);">Delete Entry</button>
</div>
<script>
function delete(id) {
$.ajax({
url: '/entry.php,
data: { 'entryId': id },
type: 'DELETE',
success: function(result) {
$('#entry-' + id).remove();
},
fail: alert('Delete Record No: ' + id + ' failed')
}
</script>
Note:
Alerts are also not always great. While simple, they stop code execution and don't render well in some scenarios. I.e.: inside webviews or on mobile devices.
They also cause fullscreen to exit.
A more professional approach is to have the notification played in the DOM.
Angular Material's Snackbar is neater in that sense.

Checking if a sessions is empty, unsetting it, and then sending $_POST data onclick

I have two possible sets of information to export to another PHP page whenever i click a button.
One of them is a session. It's something like this:
$_SESSION['excel_name']['Main_'] = "Main_".date("y_m_d_Hi");
$_SESSION['excel_array']['Main_']['Plan1'] = array();
The post data sends the same information, but doesn't save it in a session to prevent conflict between too many sessions. So what i want to try, is to check if there is a session set. If there is, i'll unset it, and send the $_POST data. When there isn't, i'll set one. I have tried doing this:
session_start();
if(isset($_SESSION) && !empty($_SESSION)) {
unset($_SESSION['Main_']);
unset($_SESSION['Plan1']);
unset($_SESSION['excel_array']);
$_POST['excel_name']['Main_'] = "Main_".date("y_m_d_Hi");
$_POST['excel_array']['Main_']['Plan1'] = array();
} else {
$_SESSION['excel_name']['Main_'] = "Main_".date("y_m_d_Hi");
$_SESSION['excel_array']['Main_']['Plan1'] = array();
}
The logic might seem a little weird for some of you, but i'm almost certain it would work... But. I wanted to do this in a button. Reason being, whenever i click the button, I export the information to the next PHP page. I want to check for these conditions before sending the information, not in the moment i load the page.
Is it possible?
There is several way to do it, but before reading my answer, please note that javascript verification can be edited and exploited maliciously.
You could do an AJAX request to a php page that would implement your logic and return a code 200 or 401. Then you can act before the next page loads.

Redirect after 5 seconds but only allow the page to be accessed by the referrer

I am trying to have page1.php redirect to page2.php after 5 seconds. However page2.php needs to be a restricted page that can only be viewed if you are being sent from --> mydomain.com/page1.php and can not be accessible if you type the address manually into the address bar.
I have tried methods that use shared keys, htaccess and php HTTP_REFERRER.
I believe the issue is coming from the redirection, and I believe it is because the redirect script is not sending the HTTP_REFERRER and therefore page2.php is looking at the url sent from the redirection script as being manually entered. I have tried with a simple php redirect and javascript. Below are the two different redirect scripts I have used.
php version.
header( "refresh:5;url=page2.php" );
Javascript version.
<script type="text/javascript">
function Redirect()
{
window.location="page2.php";
}
setTimeout('Redirect()', 5000);
</script>
I have tried these with the full url and with/without http:// for example mydomain.com/page2.php.
Page2.php needs to only accept traffic from page1.php. I have no objection as to how to go about achieving this. Using shared keys or any other aspect just as long as the user can not enter the address manually and visit the page. I am also fully aware the Referrer can be spoofed however I do not have the expertise to get to advanced.
You can use session data to make sure users of page2 have passed through page 1
With the way sessions work,The encrypted string is quite secure even if it is not encrypted at all.
on page1:
session_start();
$_SESSION['secret_key'] = 'encrypted_string';
on page2:
session_start();
if($_SESSION['secret_key'] == 'encrypted_string'){
// user is authorized
echo 'You are authorized to see this page';
}
else{
echo 'Please visit page1 before accessing this page';
}
// Logic for authorized user
Or, shorter version for page2 :
if(empty($_SESSION['secret_key']) || $_SESSION['secret_key'] != 'encrypted_string'){
die('You are not authorized to view this page.');
}
echo 'only authorized user will see from here forward';
BTW, when testing, remember that once your session is set, you will have to delete sessions in browser, or use incognito to test again.
To delete cache on chrome ctrl+shift+delete and choose cookies and other
Here's how I would do it, using 3 pages.
On the landing page, include your JavaScript, this will redirect you to an intermediate page that sets a session variable before redirecting to the final page.
On the final page, check the session variable, determine whether or not to display the page, then unset the session variable (so if they try again without returning to the first page, it will no longer work).
p1.php
<?php session_start(); ?>
<script type="text/javascript">
function Redirect()
{
window.location="p12.php";
}
setTimeout('Redirect()', 5000);
</script>
p12.php
<?php session_start();
$_SESSION['secret'] = 'todays_password';
$newURL = 'p2.php';
header('Location: '.$newURL);
?>
<script type="text/javascript">
function Redirect()
{
window.location="p2.php";
}
Redirect();
</script>
p2.php
<?php session_start();
if (isset($_SESSION['secret']))
{
if ($_SESSION['secret'] == 'todays_password')
{
//The user provided the correct secret session variable
echo 'welcome. you can view this page.';
//Put all of your page content here
?>
<!-- HTML content should be in between php delimiters, like this-->
<?php
}
else
{
//The user supplied a secret code, but it was not the correct one
echo 'invalid secret.';
//You can also add code for redirecting the user back to p1 here
//Or just display an error message
}
}
else
{
//The user did not provide a secret session variable -- they most likely did not pass through p12.
echo 'error, you are unable to view this page';
//You can also add code for redirecting the user back to p1 here
//Or just display an error message
}
unset($_SESSION['secret']); //This line makes the user return to p1 every time they visit p2 -- delete this line if you only want them to visit p1 once.
?>
To make this method secure, you'd need to give each user a unique value for their secret session variable. Store this variable, along with it's timestamp when the user visits p1 both as a session variable for the client and in a server-side database. When p2 is loaded, check to see if the session value they provide is at least 5 seconds old in the database. If it is, let them see the page. Then delete the value in the database.

One time redirect

Is there a way to do a one time redirect? Where it goes to an entrance page, and says enter site, then you go to the index.html page.
the best example of what I'm trying to accomplish: www.matisyahuworld.com
There's a page order.html that's the first page you see before you can go to the index.html page
thanks
Yes, you would have to check if the user is new or not. The only way I know how to do that is to use javascript cookies :)
document.cookie = 'unique_user = second time visitor;
expires = date you want; path=/'
Of course everything is made easier with jQuery:
$.cookie("example", "foo");
The logic would be, check if your cookie exists within the clients browser, if it does, don't put up splash page and redirect straight to index.html. If there is no cookie send it to splash, splash.html, and set the cookie there.
Here is a great resource on how to do that:
Javascript Cookies
setcookie is more simple to use:
$expire=time()+60*60*24*30;
setcookie(user,visited, $expire);
if(isset($_COOKIE["user"]))
{
RedirectToURL("index.html");
}
To create function RedirectToURL
function RedirectToURL($url)
{
header("Location: $url");
exit;
}
NOTE : Above code can be used for PHP scripting.Yet it is simple .Just add the above lines in
<?PHP
and end with
?>
also you must save the file with .php extension

Categories

Resources