This is the final instalment in a three part series. In
part 1 I briefly outlined how to prevent other sites displaying your web pages within frames. In
part 2 I talked about how to allow exceptions for the rare situations when you want to allow sites to display your web pages in frames on there site.
In this final post I'm going to discuss how to detect when your web pages are displayed in frames in other sites.
If you don't know that another site is displaying your web pages in frames on their site then you can't decide whether you are prepared to accept that or not. The most basic way is just to go through your logs and visit all the sites which refer traffic to you. This approach works but it's a lot of work and far from efficient. It would be far better if there was an automated process that alerted you when a new website started displaying your content in frames.
In this post I'm going to show you how to set up this automated process. There are going to be two main parts. Firstly we need to alter the javascript snippet from
part 2 so that when a web page is displayed within a frame on a new domain a message is sent back to our server. Secondly we need to handle that signal on our server and do something useful with it. We'll do this with a small PHP script.
Javascript
One of the technologies really being talked about at the moment is AJAX (Asynchronous Javascript And XML). Not one to miss the bandwagon I'm going to use AJAX in this script. AJAX is increasingly being used as a catch-all term for fancy javascript but here I'm actually going to use asynchronous javascript. The xml part is not important for what I'm going to do here.
In essence what is going to happen is that without the page reloading a signal is going to be sent from the browser of the person viewing one of our pages back to our server saying that the site is being loaded within a frame. It will also tell us the url of that frame.
If you are already using an AJAX library then you may want to rewrite the following code using the functions provided by your library. I'm not going to use a library here as the files are generally speaking fairly large, even with
file compaction, and it will add unnecessary overhead if the library is being used only for this script. Instead I'm going to create a simple function which has all the functionality needed for this script. On with the code.
//AJAX functions
function createRequestObject() {
var req;
if(window.XMLHttpRequest){
// Firefox, Safari, Opera...
req = new XMLHttpRequest();
} else if(window.ActiveXObject) {
// Internet Explorer 5+
req = new ActiveXObject("Microsoft.XMLHTTP");
}
return req;
}
// Make the XMLHttpRequest object
var http = createRequestObject();
function sendRequest(url) {
// Open PHP script for requests
http.open('get', 'log_frames.php?url='+url);
http.onreadystatechange = handleResponse;
http.send(null);
}
function handleResponse() { }
re= /^http:\/\/(www\.scriptsearch).*/
if (top.location != self.location) {
if (re.test(top.location) == FALSE) {
sendRequest(top.location)
top.location.replace(self.location)
}
}
In comparison with the first two instalments of this series there is a lot of new code here. Most of the new code is lifted with small alterations, mainly deletions, from an
ajaxfreaks article. The three new functions, the third of which is blank, are all related to the AJAX request. I'm not going to go into detail on what they do here but if you are unsure and want to know more take a look at the ajaxfreaks article.
The final function is blank because we don't need to do anything with the response, this script is very much fire-and-forget. If for some reason it doesn't work then informing the visitor isn't going to help.
With the last few lines of the script we are on more familiar ground. In fact with the exception of sendRequest(top.location) in the nested if statement it is exactly the same as in part 2. This call to the sendRequest function will send a request to log_frames.php with the url for the frame as a GET argument.
Next, we'll store these urls using PHP.
PHP