PDA

View Full Version : Redirect to a page if found



cmatkin
11-28-2005, 08:00 AM
Hi,
I'm after a script to load a page if it is found, if not, continue to load the current page.

EG:
index.html
upon opening checks if index2.html is on the server.
if it is, then load that instead of index.html.
Else, continue on loading index.html

Regards
Craig

jscheuer1
11-28-2005, 08:38 AM
I came across this code somewhere in my travels and though I don't understand it fully, it looks like what you are after:


function getFile(filename)
{ oxmlhttp = null;
try
{ oxmlhttp = new XMLHttpRequest();
oxmlhttp.overrideMimeType("text/xml");
}
catch(e)
{ try
{ oxmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{ return null;
}
}
if(!oxmlhttp) return null;
try
{ oxmlhttp.open("GET",filename,false);
oxmlhttp.send(null);
}
catch(e)
{ return null;
}
return oxmlhttp.responseText;
}

It is actually meant to retrieve the contents of a file for use elsewhere in your code but, it will return null if the file isn't there. I think it will only work on the same domain as the page it is looking for but, according to you, that is all you need. The way to use it would be to put it in a script block in the head of your page and then just after it in the same script bock have:


if (getFile('index2.html')!==null)
window.location.replace('index2.html')

Put this all together and you've got:


<script type="text/javascript">
function getFile(filename)
{ oxmlhttp = null;
try
{ oxmlhttp = new XMLHttpRequest();
oxmlhttp.overrideMimeType("text/xml");
}
catch(e)
{ try
{ oxmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{ return null;
}
}
if(!oxmlhttp) return null;
try
{ oxmlhttp.open("GET",filename,false);
oxmlhttp.send(null);
}
catch(e)
{ return null;
}
return oxmlhttp.responseText;
}

if (getFile('index2.html')!==null)
window.location.replace('index2.html')

</script>

ddadmin
11-28-2005, 09:05 AM
Nice thinking John. :) I was just about to type up something similar, since Ajax was the only way I could think of that might work here. I haven't tested your code yet, but at a glance it looks like it should work.

cmatkin
11-28-2005, 10:24 AM
Thanks guys.
I have just tried it and it works great.
Thanks again for your help.

Regards
Craig

mwinter
11-28-2005, 07:37 PM
I came across this code somewhere in my travels and though I don't understand it fully, it looks like what you are afterIt'll work, but it's not best suited for the task as it's designed to obtain, and return, XML from the server.

If the XMLHttpRequest approach is taken then, in principle, it would best to perform a HEAD request and check the response. As a HEAD HTTP request only returns the headers that the server would normally send with a complete response, this method is quick and efficient. Unfortunately, earlier implementations of the XMLHttpRequest object in some browsers (most notably Safari) don't support HEAD requests. As I can't test how they respond, it may be wise to avoid this and use GET, despite the advantages. If, however, the behaviour is only the same as a GET request, then HEAD should still be used.

Irrespective of the transfer method, it is the response code that is important. As servers will respond to errors by sending plain or hypertext notes, the responseText property will not be null or empty except in extremely rare occasions. Though the OP reported success, I doubt it was well tested, because it fails here.


It is actually meant to retrieve the contents of a file for use elsewhere in your code but, it will return null if the file isn't there.No, it won't. It will return null if that is the value of the responseText property, or if an exception is thrown when the open or send methods are called (which I don't even think is possible). If the file doesn't exist, the server will send a 404 response and return the usual File Not Found entity so responseText will be a string.


I think it will only work on the same domain as the page it is looking for [...]It will only connect to the server that sent the current document, which is what I think you meant to say. That is a security issue, similar to the same origin policy for scripts that try to interact with frames.

The example below assumes that the server will only return a 404 error response for the failure condition. Other responses, such as 403 Forbidden, will require (minor) modifications.



var global = this;

function getRequestObject() {
var request = null;

if( ('object' == typeof global.XMLHttpRequest)
|| ('function' == typeof global.XMLHttpRequest))
{
request = new XMLHttpRequest();
} else if('function' == typeof global.ActiveXObject) {
/*@cc_on @*/
/*@if(@_jscript_version >= 5)
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
request = null;
}
}
@end @*/
}
return (request && ('object' == typeof request))
? request
: null;
}

var httpRequest = getRequestObject(),
url = 'http://www.example.com/index2.html';

if(httpRequest) {
httpRequest.open('HEAD', url, false);
httpRequest.send(null);

if(404 != httpRequest.status) {
location.replace(url);
}
}
All that said, this whole approach is less than reliable, not least because not only will it rely on client-side scripting, but also on a feature that isn't implemented everywhere. If a server-side language (like PHP) is available, this can be done much better and quicker on the server.

Mike

jscheuer1
11-29-2005, 08:48 AM
To narrow things down from a different angle, one could test the output for a string that would only be on the page if it is there:


<script type="text/javascript">
function getFile(filename)
{ oxmlhttp = null;
try
{ oxmlhttp = new XMLHttpRequest();
oxmlhttp.overrideMimeType("text/xml");
}
catch(e)
{ try
{ oxmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{ return null;
}
}
if(!oxmlhttp) return null;
try
{ oxmlhttp.open("GET",filename,false);
oxmlhttp.send(null);
}
catch(e)
{ return null;
}
return oxmlhttp.responseText;
}

if (getFile('index2.html')&&getFile('index2.html').indexOf('Welcome to Index2')!==-1)
window.location.replace('index2.html')

</script>

Twey
11-29-2005, 06:18 PM
Mike's solution is more efficient, as John's involves downloading the entire page.

jscheuer1
11-29-2005, 06:33 PM
I think I agree, Twey (having trouble following Mike's elegant code again). However, my method avoids the issues of Safari possibly not liking the HEAD request and the possibility that something other than what is expected may be returned for a missing page. Instead of testing for a 'missing' response over which we have no control and can only guess, it tests for a known string on the sought after page.

After seeing what Opera makes of my code (nothing), I tend to agree with Mike when he says:


If a server-side language (like PHP) is available, this can be done much better and quicker on the server.

cmatkin
11-29-2005, 07:21 PM
Thanks for the quick responses.
I dont have access to any server side scripting. I am running this on an embeded microcontroller that i wrote the code for.

I have not done any html programming in any language so i asked here.

I have seen all of the examples and to me they look good. I was wondering if there is a way to check to see if a file is physically there?

Thanks for your help.

Regards
Craig

Twey
11-29-2005, 08:33 PM
Of course a server-side language would be better if available. I would, if I were you, use both in conjunction with one another:
var global = this;

function getRequestObject() {
var request = null;

if( ('object' == typeof global.XMLHttpRequest)
|| ('function' == typeof global.XMLHttpRequest))
{
request = new XMLHttpRequest();
} else if('function' == typeof global.ActiveXObject) {
/*@cc_on @*/
/*@if(@_jscript_version >= 5)
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
request = null;
}
}
@end @*/
}
return (request && ('object' == typeof request))
? request
: null;
}

var httpRequest = getRequestObject(),
url = 'http://www.example.com/index2.html';

if(httpRequest) {
try {
httpRequest.open('HEAD', url, false);
} catch(e) {
httpRequest.open('GET', url, false);
}
httpRequest.send(null);

if(404 != httpRequest.status) {
location.replace(url);
}
}... thus incorporating the features of both. Notes:
- I don't have any experience of handling exceptions in Javascript, so I'm using the Java approach (as minimally as possible);
- I'm assuming that Safari's XMLHttpRequest object will throw an exception if one attempts to use HEAD;
- What on earth are those /*@ things? :confused: A form of conditional comment for Javascript?

I was wondering if there is a way to check to see if a file is physically there?By which you mean what? Examine the inodes? :) This is as close to "physically" as you're going to get, using Javascript.

mwinter
11-29-2005, 10:07 PM
Mike's solution is more efficient, as John's involves downloading the entire page.That is very true (I said it myself ;)), but it may not matter.

If the server sends headers for the target resource that will allow it to be cached (Last-Modified and ETag headers, preferably including Expires and Cache-Control: max-age, too), then by the time the client-side 'redirect' occurs, the document will have effectively been pre-loaded. The only concern is how long the viewport will remain blank whilst this process occurs, which is why both the target and any error document must be small (less than 15KB, assuming it's on the Web). If it is much larger than this, then dial-up users (still a very large proportion of Internet users) will be wondering what on Earth is going on.



However, my method avoids the issues of Safari possibly not liking the HEAD requestChange 'HEAD' to 'GET' in the code I posted, and it will, too. :p


and the possibility that something other than what is expected may be returned for a missing page.A server should only return 404 unless the file that the OP will be looking for is more than simply missing. Even if it did return another value, or more than one depending on certain conditions, I doubt the OP would find it difficult to construct a more accomodating condition expression once shown the right syntax (if necessary).


Instead of testing for a 'missing' response over which we have no control and can only guess, it tests for a known string on the sought after page.But that then depends on that string remaining within the document forever, or incurring a maintenance penalty. That in itself is an unknown to us.

I would be very surprised if anything more than 404 File Not Found was the result.


After seeing what Opera makes of my code (nothing) [...]That's because Opera doesn't support the overrideMimeType method. As conforming ECMAScript implementations should make run-time errors catchable exceptions, Opera will first catch that, then throw an exception in the IE code path, and upon catching that, return null.

In this instance, the overrideMimeType method call can be omitted, but the getRequestObject method I posted is more graceful when it fails only returning null.



I dont have access to any server side scripting. I am running this on an embeded microcontroller that i wrote the code for.I'm a little confused here. Why would using an embedded microcontroller preclude you from using a server-side language? If you're using an XMLHttpRequest object to connect to a server, that shouldn't matter, or is your server run by this microcontroller?


I was wondering if there is a way to check to see if a file is physically there?Only if you can use a server-side language, which you say you cannot. If however, this is all run locally, you might be able to if the script host provides access to the file system (like IE with low security settings). I doubt that is the case though - I'm just mentioning possible avenues of approach.



I don't have any experience of handling exceptions in Javascript, so I'm using the Java approach (as minimally as possible)Your syntax is fine, though in general, exceptions should be avoided unless you're happy with older browsers erroring out (I'm not).


I'm assuming that Safari's XMLHttpRequest object will throw an exception if one attempts to use HEADQuite an assumption. :D I wish I knew. :(


What on earth are those /*@ things? A form of conditional comment for Javascript?Conditional comments for JScript (so a proprietary mechanism). As JScript versions prior to 5 (so generally any version of IE4) don't support exception handling, that part of the script will be hidden from it. Furthermore, as those versions are less likely to provide access to an XMLHttpRequest object, and the script and document should degrade sensibly in its absence anyway, it doesn't matter so much if they are excluded for the benefit of more recent (and prevalent) versions.

Mike

jscheuer1
11-29-2005, 10:37 PM
Instead of testing for a 'missing' response over which we have no control and can only guess, it tests for a known string on the sought after page.


But that then depends on that string remaining within the document forever, or incurring a maintenance penalty. That in itself is an unknown to us.

Not known to 'us' but, known to the user of this method. Maintenance is a potential problem but, the string in question could be a comment and therefore, unlikely to change with updating, especially if it has language like so:


<!-- This comment must remain for proper functioning of a script that tests for the existence of this file: Test String 11a -->

If he understands how to use them, cmatkin can probably use any of these methods if they work for him.

cmatkin,

Whichever you use, test it in a few different browsers, or give us the url, so we can. If you go with my method, Mike's right about my first version not being likely to work live, so in that case use the version at from Post_6 (http://www.dynamicdrive.com/forums/showpost.php?p=22035&postcount=6) in this thread.

dk2l
08-12-2011, 09:07 AM
It is working in Local Machine and INTRANET with Security confirmation.

But not working in Windows online hosting.

djr33
08-12-2011, 07:26 PM
Why are you replying to a 5 year old discussion?
What code are you using? Why not try some more modern code? (This may still work, but if it doesn't work, it probably is because browsers and servers are a little different than 5 years ago.)
Unless you have a direct response to this discussion, please post a new thread.