I have a situation like this.
<php>
<redirect the page >
<exit>
<javascript>
<redirect the page again>
I want to have javascript that basicall disables the PHP redirect. So if Javascript is enabled on the browser, the javascript redirect will work, if it disable, the PHP redirect will work. Should I just enclose the PHP code in span and make it invisible? Any ideas?
Addition ok this is not a simple redirect. the form authentication is rather odd. Register.php -> register_submit.php -> Was there an error -> yes go back to register.php (everything is javascript at this point). What I have added is PHP authentication as well so if I see javascript is not enabled, I take the user to register.php *after it does the regular checking of fields *.
PHP is a server-side technology. By the time Javascript even sees what's happened, it's too late.
Short answer, JS can't intercept/block PHP (as long as PHP is being called first).
Order of events:
Client requests page
PHP executes and generates output of page
Browser receives output
Browser begins parsing what was sent by what PHP already spit out.
Remove your PHP redirection and add this in your <head>:
<noscript>
<meta http-equiv="refresh" content="0; http://www.example.com/1" />
</noscript>
<script>
window.location = 'http://www.example.com/2';
</script>
This will redirect to http://www.example.com/1 when javascript is disabled, and to http://www.example.com/2 when it's enabled.
PHP code is executed on the server-side, while JS is client-side. So with that structure the PHP will kick in before the JS is executed. If you want JS to control PHP you need to make use of AJAX to control it.
Also enclosing PHP code in a "span" won't have any effect.
Javascript and PHP do not directly interact (exceptions apply, don't worry about them now :D). The best way to implement this type of interaction between these two disparate languages is to use the query string or cookies.
I think there may be some confusion here about when and how PHP is executed as opposed to when and how javascript is executed. Think of PHP as the factory - the goods are physically produced there. Think of your server as the loading dock, the internet as the shipping company. Your browser is the store, HTML is the shelves; Javascript is the window decorations on the store that sells the merchandise. The window decorations have no affect on the production, the factory can make some window decorations, but it doesn't use them, it just ships them right along with the merchandise for the store to use. PHP is the factory, javascript is the decoration. There are some problems with taking this analogy too literally, but there it is in a nutshell.
You can make the PHP redirect conditional on the presence or absence of a specific query string variable:
<?php
// redirect if $_GET['no_redirect'] is NOT set. Reverse the true/false to invert this rule
$do_redirect = (isset($_GET['no_redirect']) === false ? true : false);
// perform the redirect, if required
if ($do_redirect === false)
header('Location:http://mydomain.com');
?>
Javascript:
window.location = 'http://mydomain.com/?no_redirect=1';
EDIT If you're trying to detect if javascript is enabled, then the best way is for javascript to set a cookie if it is enabled. PHP can then check for this cookie, and if it isn't found then you'll know that javascript didn't get a chance to set it, so it must be disabled (or the user edited their cookies).
Take a look at some code snippets for dealing with cookies in javascript, and check out the documentation for dealing with cookies in PHP.
Related
using JS : (in <head> tag)
<script>window.location="https://stackoverflow.com";</script>
using PHP : (in <head> tag)
header('Location: https://stackoverflow.com');
end();
Which one I should use ? or another ?
and what about using <meta>?
<meta http-equiv="refresh" content="0;url=https://stackoverflow.com"/>
Many good answers , I don't know which answer I will accept, Thanks so much
The result is same for all options. Redirect.
<meta> in HTML:
Show content of your site, and next redirect user after a few (or 0) seconds.
Don't need JavaScript enabled.
Don't need PHP.
window.location in JS:
Javascript enabled needed.
Don't need PHP.
Show content of your site, and next redirect user after a few (or 0) seconds.
Redirect can be dependent on any conditions if (1 === 1) { window.location.href = 'http://example.com'; }.
header('Location:') in PHP:
Don't need JavaScript enabled.
PHP needed.
Redirect will be executed first, user never see what is after. header() must be the first command in php script, before output any other. If you try output some before header, will receive an Warning: Cannot modify header information - headers already sent
A better way to set the location in JS is via:
window.location.href = 'https://stackoverflow.com';
Whether to use PHP or JS to manage the redirection depends on what your code is doing and how. But if you're in a position to use PHP; that is, if you're going to be using PHP to send some JS code back to the browser that simply tells the browser to go somewhere else, then logic suggests that you should cut out the middle man and tell the browser directly via PHP.
It depends on how and when you want to redirect the user to another page.
If you want to instantly redirect a user to another page without him seeing anything of a site in between, you should use the PHP header redirect method.
If you have a Javascript and some action of the user has to result in him entering another page, that is when you should use window.location.
The meta tag refresh is often used on download sites whenever you see these "Your download should start automatically" messages. You can let the user load a page, wait for a certain amount of time, then redirect him (e.g. to a to-be-downloaded file) without Javascript.
PHP redirects are better if you can as with the JavaScript one you're causing the client to load the page before the redirect, whereas with the PHP one it sends the proper header.
However the PHP shouldn't go in the <head>, it should go before any output is sent to the client, as to do otherwise will cause errors.
Using <meta> tags have the same issue as Javascript in causing the initial page to load before doing the redirect. Server-side redirects are almost always better, if you can use them.
The first case will fail when JS is off. It's also a little bit slower since JS must be parsed first (DOM must be loaded). However JS is safer since the destination doesn't know the referer and your redirect might be tracked (referers aren't reliable in general yet this is something).
You can also use meta refresh tag. It also requires DOM to be loaded.
window.location.href = 'url';
is beter than
header('location:url');
because the header command is mustly return an error "Warning: Cannot modify header information - headers already sent"
using js window.location.href = 'url';
this is beter
I want to detect whether or not a user is viewing a secure page and redirect if not (for logging in).
However, my site travels through a proxy before I see the server variables and the proxy (right now) is telling me that $_SERVER['HTTPS'] is 'on' when the URI clearly indicates otherwise. It also shows 'on' when the user is navigating 'securely'.
Navigating through http:// and https:// both output that $_SERVER['SERVER_PORT'] = 443.
I don't have the ability to make any changes to the proxy so I want to know:
Does PHP have any other options for me to detect the truth or...
Am I stuck to resort to JavaScript's mechanisms for detection and redirection.
I mined this question for ideas but they mostly revolve around the $_SERVER['HTTPS'] variable being trustworthy. Bah!
It appears that this question is experiencing at least something similar, but s/he was able to resolve it by adapting an apache solution.
Are there any other PHP SERVER variables or tricks available to detect what the user's URI begins with? The only difference between the $_SERVER variables when my site is viewed http versus https are the following:
_FCGI_X_PIPE_ (appears random)
HTTP_COOKIE (sto-id-47873 is included in the non-secure version but I did not put it there)
REMOTE_ADDR (This and the next two keep changing inexplicably!)
REMOTE_HOST
REMOTE_PORT ('proxy people', why are you continually changing this?)
Are any of these items strong enough to put one's weight upon without it splintering and causing pain later? Perhaps I shouldn't trust anything as filtered through the proxy since it could change at any given time.
Here is my plan to use JavaScript for this purpose; is it the best I have?
function confirmSSL() {
if(location.protocol != "https:") {
var locale = location.href;
locale = locale.replace(/http:\/\//,"https://");
location.replace(locale);
}
}
<body onLoad="confirmSSL()">...
I think if the user has JavaScript disabled in my community, then they hopefully know what they are doing. They should be able to manually get themselves into a secure zone. What sort of <noscript> suggestions would be commonplace / good practice? Something like this, perhaps?:
<noscript>Navigate using https://blah.more.egg/fake to protect your information.</noscript>
PHP solutions that work (with good explanation) will be given preference for the correct answer. Feel free to submit a better JavaScript implementation or link to one.
Many thanks!
Although already partially discussed in the question's comments, I'll summarize some suggestions concerning the redirection logic in JavaScript:
Generally using window.location instead of location is advisable, an explanation can be found here.
Regex seems like a bit of an overkill for a simple replacement of the protocol.
The redirection logic should be executed as soon as possible, because in the event of redirection, every additional document processing is unnecessary.
Browsers with JavaScript disabled should at least show a notification prompting the user to switch to https.
I suggest using the following code (adopted from here), which is short and efficient:
<head>
<script type="text/javascript">
if (window.location.protocol != "https:") {
window.location.href = "https:" + window.location.href.substring(window.location.protocol.length);
}
</script>
...
</head>
<body>
...
<noscript>Please click here to use a secure connection!</noscript>
...
Just use the client-side approach. If your proxy is non-configurable, then that option is out. Detecting and redirecting via js is fine.
There is also a way to achieve the redirection without client side javascript. This method can be especially helpful, if JavaScript is disabled in the client's browser.
The steps are pure PHP and pretty simple:
Start a session
If it's a fresh session, redirect to the https location
If the session isn't new, it can be assumed, that the user has been redirected
Example code:
<?php
session_start();
if( !isset($_SESSION['runningOnHttps']) ) {
$_SESSION['runningOnHttps'] = true;
header('Location: https://my-cool-secure-site.com');
}
?>
Naturally, you could restrain this functionality to those browsers with JavaScript disabled in order to create a kind of 'hybrid mode': Whenever there is a new session with a non-JS browser, make a request to some kind of callback script that notifies the server to send a location header:
some_landingpage.php sends an initial <noscript> containing a hidden iframe, which will load redirect.php:
if( !isset($_SESSION['checkWasMade']) ) {
$_SESSION['checkWasMade'] = true;
echo '<noscript>
<iframe src="redirect.php" style="visibility: hidden; position: absolute; left: -9000px;"></iframe>
</noscript>';
}
A request to redirect.php will let you know, that JavaScript is disabled and give you the chance to force redirection by sending a Location header (see above) with the next actual request.
As a matter of course, this method will only work reliably, if the protocol won't change (magically?) during one session.
UPDATE:
All of the above-mentioned method for handling non-JavaScript user agents could be rendered moot by an even neater approach:
I just learned, that <noscript> can also be included inside the <head>, which allows one to just redirect via <meta> tags.
Hence, some_landingpage.php could send an initial meta-refresh inside <noscript>:
// The following echo must appear inside the html head
if( !isset($_SESSION['checkWasMade']) ) {
$_SESSION['checkWasMade'] = true;
echo '<noscript>
<meta HTTP-EQUIV="REFRESH" content="0; url=https://my-cool-secure-site.com">
</noscript>';
}
I am trying to delay PHP execution until a cookie is set through JavaScript. The code is below, I trimmed the createCookie JavaScript function for simplicity (I've tested the function itself and it works).
<?php
if(!isset($_COOKIE["test"])) {
?>
<script type="text/javascript">
$(function() {
// createCookie script
createCookie("test", 1, 3600);
});
</script>
<?php
// Reload the page to ensure cookie was set
if(!isset($_COOKIE["test"])) {
header("Location: http://localhost/");
}
}
?>
At first I had no idea why this didn't work, however after using microtime() I figured out that the PHP after the <script> was executing before the jQuery ready function. I reduced my code significantly to show a simple version that is answerable, I am well aware that I am able to use setcookie() in PHP, the requirements for the cookie are client-side.
I understand mixing PHP and JavaScript is incorrect, but any help on how to make this work (is there a PHP delay? - I tried sleep(), didn't work and didn't think it would work, since the scripts would be delayed as well) would be greatly appreciated.
It is not impossible to do what you are trying to do, as other answers have stated, but it is also not trivial and seriously a bad idea for your server to wait per-request for the client to "set a cookie."
But it can be done.
PHP code would write a <script> block for setting the cookie.
PHP code would begin an idle loop, monitoring a session variable. Not a cookie. The cookies for the PHP script executing are already set and are not going to change by JavaScript.
JavaScript block written in #1 would also need to make an AJAX call to the server. The PHP script it calls should set the cookie you care about, but also set the session variable #2 cares about.
The original script, monitoring the session, should wake up and continue as you planned.
While PHP does execute before JavaScript, all browsers incrementally load the HTML/CSS/JavaScript content generated by PHP (or any server-side language). Because of the incremental loading, it is possible for your PHP script to delay for JavaScript to do something (as outlined above) before continuing. But your server is going to have a lot of headache to deal with, such as how long to wait for JavaScript to break the idle loop in #2 if the JavaScript request never comes through, etc.
This is not a normal execution flow for a standard webpage. Unless you really need this, perhaps consider this a proof-of-concept answer.
PHP executes first in its entirety on the server. It then sends the final HTML/Javascript/CSS output to the browser. The browser receives this and executes any Javascript.
It is fundamentally impossible to do what you're trying to do with that code. PHP and Javascript run at completely different times in completely different environments. You need to start another request to the server once Javascript set the cookie to start another PHP script. Redirect using Javascript or look into AJAX.
If you want to execute JavaScript before PHP, you'll have to divide it into two requests. You can load your JavaScript in one request, and execute an Ajax request after your cookie is set. Keep in mind that all server-side code is processed before the client-side code will be executed.
I have to ask though.. why do you want to do it this way? What are you trying to accomplish?
Cookies can be set in PHP with setcookie
setcookie("test",1,time()+3600);
This can't be done within a single request. PHP runs first, then JavaScript. Even incremental loading won't help, because cookies are sent via headers and those have already been sent by the time PHP runs.
However, you can let the JavaScript set the cookie and then reload the page once it's done by using location.reload(). PHP would then only need to print the JavaScript, like so:
<?php
if(!isset($_COOKIE["test"])) {
?>
<script type="text/javascript">
$(function() {
// createCookie script
createCookie("test", 1, 3600);
// reload the page, which would send the cookie at the next request
location.reload();
});
</script>
<?php
// stop execution and wait for JavaScript to call you again.
exit;
}
?>
The PHP executes on the server-side, the JS on the client-side. In a single GET request from the browser, the PHP will always execute before the JS.
i've got a slight problem with JS enabled detection.
not too big, because i know i'm on the right track.
but here's my deal:
when i try to set a cookie in JS (jQuery) using this code
$(window).load(function(){
$.cookies.set('c_jsEnabled', 'true');
});
or just in plain JS using this code
function setCookie()
{
document.cookie='c_jsEnabled=true';
}
<body onload="setCookie();">
and then try to detect it in PHP using this code
if($_COOKIE['c_jsEnabled'] == 'true')
{
if(file_exists('./main.php'))
{
require_once ('./main.php');
}
echo getIndex();
}
else
{
if(file_exists('./noJS.php'))
{
require_once ('./noJS.php');
}
echo getIndex();
}
setcookie('c_jsEnabled', '');
it takes 2 page refreshes to actually get the right value into PHP.
my guess is that this bascially means that the PHP script is executed before the JS function is fired.
could this be because all codes shown above are in the same script (index.php)?
This is kind of a problem for me, because i want to prevent people from using my website when they have JS disabled.
is there a way to set the cookie before php tries to get the cookie variable?
PHP is always "fired" before JavaScript because PHP is processed on the server and then sends out the HTML and JavaScript for the browser to process and render. You can never expect JavaScript to execute before PHP for this reason.
In your case, use JavaScript to set the cookie and then do a redirect to refresh the page so PHP can get the cookie value and act accordingly.
You should be setting the cookie directly from the PHP file. That way, you know that it exists, and more importantly, you have control of the cookie. You can set it from the client, but that will always execute after the HTML has been sent to the browser, so the PHP file won't get it until the next request.
PHP only sends the cookie header when content is sent to the browser. Javascript then executes after that, so you would need a second load of the page to detect the cookie.
This can trigger infinite redirection loops (especially if the user has cookies disabled), so be careful.
To disable the site to users without Javascript, consider the following.
<div id="noscript" style="width:100%; height:100%; z-index:999; position:absoloute; top:0px; left:0px; background-color:#CC9900; display:block">
Please Enable Javascript!</div>
<script type="text/javascript">
document.getElementById('noscript').style.display = 'none';
</script>
I find the <noscript> tag is unreliable (there was a bug in iOS causing it to only show when there was Javascript, if I remember correctly).
A second option:
You can have the PHP check for a cookie. If it isn't set, have it redirect (header("Location: aaa.html");) to a page with the Javascript to set the cookie and redirect back. (Alternatively, have the PHP output Javascript to set the cookie reload the page.) You then only have to worry about users who "spoof" the cookie, although you will also lock out users who have cookies disabled.
Nope - PHP will always be called before client-side JavaScript, so with this method you'll always have to refresh the page at least once. You're better to develop your site so that non-JS users have a worse-but-still-acceptable experience, or at worst use the <noscript> HTML tag to serve alternative content to those users.
You can't get a cookie in PHP that's being set by JavaScript before the page renders/executes.
You could set the cookie using PHP, however. That will ensure it's set and available regardless of JavaScript or multiple page refreshes.
I'm building a proxy and am trying to deal with a page that uses javascript. The page has a button like this:
<input type="submit" ...cut this out... onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(...cut this out...)) />
When I click this button from my proxy the URL is rewritten to look like this (notice the javascript code inserted here):
http://domain.com/proxy/index-new.php?q=https://proxiedomain.com/javascript:WebForm_DoPostBackWithOptions(new%20WebForm_PostBackOptions(...cut this out...))
I'm not sure how I can handle this in my proxy server. When I don't use a proxy the headers are sent to a completely different page (the URL doesn't include this javascript). Can anyone give me any hints as to what I should look into or read to understand this problem better? From what I understand so far, I need this javascript to be executed (which would require a cient browser).
Any link that points to javascript:... will run JavaScript but not necessarily load a page.
I would leave these links alone, and instead ensure that the form action URL is set to your proxy, and any location.href = 'http://www.example.com/fully_qualified_urls'; are swapped for the proxy URL.
e.g. a simple RegEx replace of "OLD_URL" for "NEW_URL" (accounting for any HTTP vs. HTTPS protocol differences) should suffice for the most part.
Note: I'm aware it isn't "simple", but trying to inspect a javascript: based "link" to modify its behavior will be very awkward.