I'm trying to write a little script that reads the searchterms from
the document.referrer.
Unreliable, especially client-side.
But when I run it, I get no alerts. What am I
doing wrong? All help is appreciated
-----------------------------------------------------
detectSearch("
http://www.google.com?q=dattum");
var sniffs = {
'/google\./i' : 'q',
'/yahoo\./i' : 'p'
}
function detectSearch(uri) {
for (var sniff in sniffs) {
if (uri.match(sniff)) {
alert(getArg(uri, sniffs[sniff]));
Should be
window.alert(...);
The argument of String.prototype.match() is expected to be a reference to a
RegExp object. If it is not, it is converted to such an object (ES3,
15.5.4.10). However, "/google\./i" or "/yahoo\./i" are not converted to
`/google\./i' or `/yahoo\./i'.
Instead, the names of the enumerable properties of `sniffs' are `/google./i'
and `/yahoo./i' (as you can test with window.alert("/google\./i")), and so
the Regular Expressions matched against are /\/google.\/i/ and /\/yahoo.\/i/
(as you can test with `window.alert(new RegExp("/google\./i"))') for which
there was no match.
However, even if you did not use the leading and trailing `/'s and escaped
the dot properly, your Regular Expressions were hardly sufficient as they
would also match
http://example.com/google.html
Consider
'https?://([^.]+\\.)*google\\.[^./]+'
instead.
An alternative would be to use an array of augmented Object objects, in
which case you could write the RegExp literal "as is":
var sniffs = [
{expr: /^https?:\/\/([^.]+\.)*google\.[^.\/]+/i, param: 'q'},
{expr: /^https?:\/\/([^.]+\.)*yahoo\.[^.\/]+/i, param: 'p'}
];
function detectSearch(uri)
{
for (var sniff in sniffs)
{
if (uri.match(sniffs[sniff].expr))
{
window.alert(getArg(uri, sniffs[sniff].param));
}
}
}
But considering that you have much the same expressions here, the following
would suffice:
var sniffs = [
{domain: 'google', param: 'q'},
{domain: 'yahoo', param: 'p'}
];
function detectSearch(uri)
{
for (var sniff in sniffs)
{
if (uri.match('^https?://([^.]+\\.)*' + sniffs[sniff].domain
+ '\\.[^./]+'))
{
window.alert(getArg(uri, sniffs[sniff].param));
}
}
}
And then you could go back to your approach as well:
var sniffs = {
google: 'q',
yahoo: 'p'
};
function detectSearch(uri)
{
for (var sniff in sniffs)
{
if (uri.match('^https?://([^.]+\\.)*' + sniff + '\\.[^./]+'))
{
window.alert(getArg(uri, sniffs[sniff]));
}
}
}
function getArg(uri, arg) {
var args = [];
You don't use that variable.
uri = uri.substr(uri.indexOf("?") + 1, uri.length);
The second argument is optional, the default is the string length already.
for (var i = 0; i < uri.split("&").length; i++) {
if (uri.split("&").split("=")[0] == arg) {
return uri.split("&").split("=")[1];
}
}
}
Consider
/**
* @see http://PointedEars.de/scripts/types.js
*/
function isMethodType(s)
{
return /\b(function|object)\b/i.test(s);
}
/**
* @see http://PointedEars.de/scripts/string.js
*/
var esc = (function()
{
return (
isMethodType(typeof encodeURIComponent) && encodeURIComponent
? function(s) { return encodeURIComponent(s); }
: (isMethodType(typeof escape) && escape
? function(s) { return escape(s); }
: function(s) { return s; }));
})();
var unesc = (function()
{
return (
isMethodType(typeof decodeURIComponent) && decodeURIComponent
? function(s) { return decodeURIComponent(s); }
: (isMethodType(typeof unescape) && unescape
? function(s) { return unescape(s); }
: function(s) { return s; }));
})();
function getArg(uri, arg)
{
var m = uri.match(new RegExp("[?&]" + esc(arg) + "=([^&#]+)"));
return m && unesc(m[1]) || "";
}
instead.
PointedEars