Ad

Redirect 404 To Similar Pages In Javascript

- 1 answer

In my website, I want to be able to redirect to any users who get a 404 error to be redirected to the page with the closest(most similar) name to the one that got the 404 error. For example, let's say that I had a simple website with just a few pages.

var pages = ["index.html", "contact.html", "calander.html", 
"otherpage.html", "similarpage1.html" "similarpage2.html"]

Of course, I also have a page titled 404.html which is my 404 page, but I want it to be so when the user gets a 404 error, they can click a button to get redirected to a recommended page, which is the page that I described above(the page that's name is the most similar to the page which the user is on right now that has generated a 404 error.)


Edit: I only want to use client side code to do this since I'm using github pages to host this website, and also, If the title does not match anything(such as if someone requests test.html), I want it to redirect it to the home page. also, know kind of how I could do this using the levenshtein distance, but I don't know how to actually get started coding it.

Ad

Answer

For these types of tasks, I like to use the levenshtein distance.

Here's a JavaScript implementation:

/*
Copyright (c) 2011 Andrei "snippet-code">
/*
Copyright (c) 2011 Andrei Mackenzie
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

// Compute the edit distance between the two given strings
function distance(a, b) {
  if (a.length == 0) return b.length;
  if (b.length == 0) return a.length;
  var matrix = [];

  // increment along the first column of each row
  var i;
  for (i = 0; i <= b.length; i++) {
    matrix[i] = [i];
  }

  // increment each column in the first row
  var j;
  for (j = 0; j <= a.length; j++) {
    matrix[0][j] = j;
  }

  // Fill in the rest of the matrix
  for (i = 1; i <= b.length; i++) {
    for (j = 1; j <= a.length; j++) {
      if (b.charAt(i - 1) == a.charAt(j - 1)) {
        matrix[i][j] = matrix[i - 1][j - 1];
      } else {
        matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
          Math.min(matrix[i][j - 1] + 1, // insertion
            matrix[i - 1][j] + 1)); // deletion
      }
    }
  }

  return matrix[b.length][a.length];
};


var pages = ["index.html", "contact.html", "calander.html",
  "otherpage.html", "similarpage1.html",
  "similarpage2.html"
];

function closest(page) {
  var smallest = -1;
  var rtn;
  for (var i = 0; i < pages.length; i++) {
    var dist = distance(page, pages[i]);
    if (dist < smallest || smallest == -1) {
      smallest = dist;
      rtn = pages[i];
    }
  }
  return rtn;
}

var test = ['indez.htm', 'contacts.html', 'calandar.htm', 'otherage.htm', 'simlarpag.htm', 'similarpage'];
var out = "";

for (var i = 0; i < test.length; i++)
  out += "Closest page for <b>" + test[i] + "</b> is <b>" + closest(test[i]) + "</b><br>";


document.getElementById("output").innerHTML = out;
<div id="output"></div>

Now you within 404.html, you can use the pageName to determine which page to suggest:

document.write(
    "Couldn't find this page. Maybe you wanted " +
    closest(location.pathname) + "?");
Ad
source: stackoverflow.com
Ad