Coding with Jesse

Redirecting after POST

When working with forms, we have to think about what will happen when someone clicks back or forward or refresh. For example, if you submit a form and right afterwards refresh the page, the browser will ask if you want to resend the data (usually in a pretty long alert box talking about making purchases).

People don't always read alert boxes, and often get used to clicking OK all the time (I know I fall in this category), so sometimes comments and other things get submitted more than once.

To solve this, you can simply do an HTTP redirect after processing the POST data. This is possible with any server-side language, but in PHP it would look something like this:

if (count($_POST)) {
    // process the POST data
    add_comment($_POST);

    // redirect to the same page without the POST data
    header("Location: ".$_SERVER['PHP_SELF']);
    die;
}

This example assumes that you process the form data on the same page that you actually want to go to after submitting. You could just as easily redirect to a second landing page.

On this site, on each blog post page, I have a form that submits to the same blog post page. After processing the comment, I send a redirect again to the same page. If you add a comment and then refresh, or click back and then forward, the comment won't be submitted twice. (However, if you click back and then click Add Comment again, it will. I really should filter out duplicates, but that's another topic.)

This works because you essentially replace a POST request with a GET request. Your browser knows that POST requests are not supposed to be cached, and that you should be warned before repeating a POST request. After the redirect, the page is the result of a simple GET request. Refreshing the page simply reloads the GET request, leaving the POST request lost between the pages in your browser history.

Published on May 22nd, 2007. © Jesse Skinner

Helping visitors with .htaccess

When I changed all my URLs, I put in place something to email me whenever there was a 404 (page not found). This way, if I screwed up something with my forwarding, I'd know.

It turned out that people were getting 404s mostly for one of two mistakes. Either there was spaces in the URL (an error of copying and pasting perhaps?), or there was a trailing period at the end of the URL (probably from it being part of a sentence, and the period becoming part of the URL when auto-linked).

The two broken URLs look like this:

http://www.thefutureoftheweb.com/blog/helping-visitors-with-htac cess

http://www.thefutureoftheweb.com/blog/helping-visitors-with-htaccess.

I thought I'd make things easier for people by auto-correcting these two mistakes. I added a few lines to my .htaccess file like so:

RewriteEngine on

# remove spaces in URL as a favour to visitors
RewriteCond %{REQUEST_URI} .+\s+.+
RewriteRule ^(.+)\s+(.+)$ /$1$2 [L,R=301]

# remove trailing periods on URL as a favour to visitors
RewriteCond %{REQUEST_URI} \.+$
RewriteRule ^(.*)\.+$ /$1 [L,R=301]

Unlike my major changes the other day, I'm not obliged to maintain these rewrites forever — after all, they are still mistakes in the URL, and I'm not giving out URLs with spaces and dots in them on purpose. However, I'd rather bring people to the correct page if I can.

Published on May 21st, 2007. © Jesse Skinner

Resizing a web layout based on browser size

Some people thought that my new layout was too thin, and I had to agree. Originally, I wanted the width of the text on the page to be in a more narrow, more readable column. I also tried to stick to a layout that could fit within a browser on an 800x600 resolution. The result was a column of text that was less readable because it was too narrow.

Today, I added a bit of JavaScript to the page to resize the layout for anyone with a browser wider than 930px. The JavaScript looks like this:

var body_check = setInterval(function(){
    if (document.body) {
        clearTimeout(body_check);

        if (document.body.clientWidth > 930)
            document.body.className += ' wide';
    }
}, 10);

Every 10ms, this script checks if the body is available yet. As soon as it is, the checking is cancelled, and the 'wide' class is added to the body if the browser is wider than 930px.

I opted for a polling technique instead of using window.onload, or even instead of addDOMLoadEvent, so the design wouldn't noticeably jump when the class was added.

To go along with this JavaScript, I added the following in the CSS:

#body { width: 760px; }
#main h1 { width: 560px; }
#main .section { width: 444px; }

body.wide #body { width: 910px; }
body.wide #main h1 { width: 710px; }
body.wide #main .section { width: 594px; }

I isolated the 3 fixed widths that would need to change, and simply increase each of them by 150px whenever the 'wide' class is added to the body.

I hope this wider design is a bit more readable for the 98% of you with a higher resolution.

Published on May 19th, 2007. © Jesse Skinner

A URL is (maybe not) forever

Last year, I wrote that A URL is forever. Well, like any good hypocrite, I went and changed my URLs yesterday.

I used to have URLs like:

/blog/2007/5/a-url-is-maybe-not-forever

Originally I thought having the date in there would make my site more scalable, so in 100 years (ha!), I wouldn't have a problem of finding a unique URL for my blog posts. Yesterday, I decided I'd rather have shorter URLs and just make myself come up with unique URLs for my blog posts (a matter of taste, really). So now my URLs look something like this:

/blog/a-url-is-maybe-not-forever

So yes, my URLs weren't forever. But I didn't just change them all and break all the old URLs. No, the original URLs all still work. To do this, I added a 301 (permanent) redirect to my .htaccess file, like this:

RewriteEngine on

# need this forever
RewriteCond %{REQUEST_URI} ^/blog/d{4}/d+/.+
RewriteRule ^blog/d{4}/d+/(.*)$ http://www.thefutureoftheweb.com/blog/$1 [L,R=301]

Now, for the life of this site, I have to support both styles of URLs (at least for all blog posts posted before today). That's a sacrifice I'll have make to have shorter URLs. And that's really what's important: once a URL is released into the wild, it should always bring someone to the page it originally referenced, even if the preferred URL for that page changes.

Published on May 17th, 2007. © Jesse Skinner
<< older posts newer posts >> All posts