Table of Contents
The symbol returns the reader to the top of the Table of Contents.
1. Introduction
Web pages provide links to other web pages, some to web pages contained within the same website; others to web pages external to the referrer's website. I refer to the latter as external links and it is those links that I discuss in this article.
This article will present a method whereby external links can be intercepted and processed.
1.1. Development Directory Structure
When I coded the JavaScript for this project, I decided to incorporate the code for intercepting redirection in master_page.js from Breadcrumbs Generation Tool [ ^ ]. Software was developed in the master-page environment and then transferred to the stand-alone environment. The stand-alone version, in a separate directory structure, is provided to avoid requiring a developer to use a master-page solution. And while modifying the JavaScript, I removed some bugs that were undetected earlier.
The directory structures for both master-page and stand-alone versions of the interception of external links are:
MasterPage_Intercept_External_Link | StandAlone_Intercept_External_Link |
Contents | |
constants.json | |
footer.ini | |
header.ini | |
menu.ini | |
menu.json | |
CSS | CSS |
master_page.css | intercept_external_link.css |
Images | Images |
favicon.ico | favicon.ico |
green_dot.png | |
ocean2.gif | |
printer.png | |
printer_hover.png | |
site_logo.png | |
under_construction.png | |
Scripts | Scripts |
master_page.js | intercept_external_link.js |
contact_webmaster.html | |
index.html | index.html |
link_1.html | link_1.html |
link_2.html | link_2.html |
link_3.html | link_3.html |
link_4.html | link_4.html |
master_pages_template.html | redirection.html |
privacy_policy.html | stand_alone_template.html |
redirection.html | |
Both directories are included in the download.
2. Using the Code
Using Breadcrumbs Generation Tool [ ^ ] as a guide, I decided that the detection of external links should be controlled by the contents of a JSON parameter declared in the <head> of each page (that is to detect external links) and then passed to build_page, the event handler for the <body> element's onload event.
In this article,
- The term "current page" refers to the HTML page that is about to be displayed, potentially containing an external link.
- The symbols < and > (note bolded) surround user supplied information.
2.1. Master Page Interception of External Links
The following are the prerequisites for detecting external linkage in a master-page environment:
2.2. Stand-alone Interception of External Links
The following are the prerequisites for detecting external linkage in a stand-alone environment:
2.3. PAGE_COMPONENTS
The PAGE_COMPONENTS parameter needs to be passed to the build_page method for both the master-page and the stand-alone environments. There are three recognized name/value pairs in the JSON object that control the processing:
Name | Value | Type |
intercept_external_links | Are external links to be intercepted? If false, interception of external links will not occur. | Boolean |
redirection_page_url | URL of the redirection alert HTML page | URL |
debug_json | Are the contents of the PAGE_COMPONENTS to be displayed? | Boolean |
For example:
<head>
<title>Home</title>
<meta http-equiv="Content-type"
content="text/html; charset=UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0" />
<script>
var PAGE_COMPONENTS =
{
"intercept_external_links":true,
"redirection_page_url":"redirection.html",
"debug_json":false
};
</script>
</head>
For master-pages PAGE_COMPONENTS, the intercept_external_links and redirection_page_url parameters are added.
In both environments (stand-alone and master-page), detecting external linkage will only occur if intercept_external_links is true and a redirection landing page URL is provided in redirection_page_url.
2.4. Redirection Landing Page
When an external link is intercepted, the redirection landing page is opened with a query string containing the href of the external link. For example, if the external link was
<a href="https://google.com">Google</a>
the redirection page would be opened by:
redirection.html?link=https%3A%2F%2Fgoogle.com
The redirection landing page for this project's stand-alone environment is:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Redirection Alert</title>
<meta http-equiv="Content-type"
content="text/html; charset=UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0" />
<link rel="icon"
type="image/x-icon"
href="Images/favicon.ico"/>
<link rel="stylesheet"
href="https://www.w3schools.com/w3css/4/w3.css" />
<link rel="stylesheet"
href="CSS/intercept_external_link.css" />
<!--
<script type="text/javascript">
var PAGE_COMPONENTS =
{
"intercept_external_links":false,
"debug_json":false
};
</script>
</head>
<body onload="InterceptExternalLinks.build_page ( PAGE_COMPONENTS );">
<div id="header"></div>
<div id="contents"
style="margin-left:20%;
margin-right:20%;
width:50%;" >
<h3 class="w3-text-red"
style="font-weight:bold;">Redirection Warning</h3>
<p>
You are now leaving this website. Links to external sites are
provided for user convenience and imply no endorsement. Note
that the privacy policy of the linked site may differ from
that of this site.
</p>
<p>
Use the browser's Back button to return to the previous page.
</p>
<p>
Proceed to <a id="next_site"
href="#"
target="_blank">this page</a> (in a new window)
</p>
</div>
<div id="footer"
style="margin-top:20px;
padding-top: 20px;" >
</div>
<script type="text/javascript"
src="Scripts/intercept_external_link.js"></script>
<script>
var link_query_string_parameter =
InterceptExternalLinks.
get_query_string_parameter ( 'link' );
link_query_string_parameter =
link_query_string_parameter.trim ( );
if ( link_query_string_parameter.length > 0 )
{
var a = document.getElementById ( 'next_site' );
a.href = link_query_string_parameter;
a.innerHTML = link_query_string_parameter;
}
</script>
</body>
</html>
For this project's stand-alone redirection landing page, the page would display as
3. Implementation
The implementation of the detection of external links is contained in the intercept_external_link.js and the master_page.js JavaScript files. The logic is the same. For this discussion, I will refer to the intercept_external_link.js.
3.1. onload Event Handler Registration
The most efficient way in which to detect a redirection to an external link is to add a click event handler to the about-to-be-displayed page.
:
if ( !components.intercept_external_links )
{
return;
}
if ( !components.redirection_page_url )
{
return;
}
var redirection_page_url_contents =
read_contents ( components.redirection_page_url );
if ( !redirection_page_url_contents )
{
return;
}
redirection_page = components.redirection_page_url;
if ( document.addEventListener )
{
document.addEventListener ( 'click',
intercept_click_event );
}
else if ( document.attachEvent )
{
document.attachEvent ( 'onclick',
intercept_click_event );
}
The intercept_click_event method is now registered as the handler for any click that occurs on the page.
3.2. intercept_click_event Event Handler
Because intercept_click_event will be triggered on every click that occurs on the page, it must react quickly when invoked. A test is made to insure that the tag name of the tag upon which a click occurred is an anchor (<a>) tag. If the test fails, the handler returns immediately.
:
var href;
var target;
:
target = e.target || e.srcElement;
if ( target.tagName.toLowerCase ( ) === 'a' )
{
href = target.getAttribute ( 'href' );
}
else if ( e.rangeParent.tagName.toLowerCase ( ) === 'a' )
{
href = e.rangeParent.href;
}
else
{
return;
}
Once that the anchor tag has been confirmed, the href of that tag is retrieved. So that we do not misinterpret pseudo protocols with external links, the following tests are performed.
:
var pieces;
:
pieces = href.toString ( ).split ( ":" );
if ( pieces.length > 1 )
{
if ( pieces [ 0 ] == "javascript" )
{
return;
}
}
If the current page does not share an origin with the href, the link is an external link. It is in this code that same origin [ ^ ] is determined and enforced. Basically if the two pages do not share the same domain then the href is an external link.
:
if ( retrieved_origin ( document.URL ) ===
retrieved_origin ( href ) )
{
return;
}
:
The retrieved_origin helper method is:
function retrieved_origin ( url )
{
var origin = parse_URL( url ).protocol.toString ( ) +
"//" +
parse_URL( url ).host.toString ( );
return ( origin );
}
and the parse_URL helper method is:
function parse_URL ( url )
{
var parser = document.createElement ( 'a' );
var query_items = { };
var query_string;
parser.href = url;
query_string = parser.search.
replace ( /^\?/, '' ).
split ( '&' );
for ( var i = 0; ( i < query_string.length ); i++ )
{
var split = query_string [ i ].split ( '=' );
query_items [ split [ 0 ] ] = split [ 1 ];
}
return { protocol: parser.protocol,
host: parser.host,
hostname: parser.hostname,
port: parser.port,
pathname: parser.pathname,
search: parser.search,
query_items: query_items,
hash: parser.hash
};
}
At this point an external link has been detected. The query string is prepared and the redirection landing page is opened.
var url = redirection_page;
var parameters =
{
link:href
};
e.preventDefault ( );
window.location.href = build_url_with_query_string (
url,
parameters );
The build_url_with_query_string helper method is:
function build_url_with_query_string ( url,
query_string_parameters )
{
var query_string = "";
for ( var key in query_string_parameters )
{
var value = query_string_parameters [ key ];
query_string += encodeURIComponent ( key ) +
"=" +
encodeURIComponent ( value ) +
"&";
}
if ( query_string.length > 0 )
{
query_string = query_string.substring (
0,
( query_string.length - 1 ) );
url = url + "?" + query_string;
}
return ( url );
}
4. References
5. Downloads
The download contains the two development directories. In the appropriate Scripts/ directory are found master_page.js and intercept_external_link.js.
The master_page.js file is found in the Scripts/ subdirectory of the MasterPage_Intercept_Redirection/ directory; the intercept_external_link.js file is found in the Scripts/ subdirectory of the StandAlone_Intercept_Redirection/ directory.
6. Practice and Experience
Master-pages detection of external links was developed first. After its development was completed, the stand-alone version was implemented by incorporating master_page.js into a new intercept_external_link.js (simply a matter of copying Javascript).
7. Conclusion
I have presented a method that provides developers with the ability to intercept and process external links.
8. Development Environment
The Intercept External Linking Tool was developed in the following environment:
Microsoft Windows 7 Professional SP 1 |
Microsoft Visual Studio 2008 Professional SP1 |
Microsoft Visual C# 2008 |
Microsoft .Net Framework Version 3.5 SP1 |
9. History
02/20/2020 | Original article |