Random Thoughts
Monday, August 10, 2009
SEO advice: Redirect wisely
More often than not you will see someone recommend switching all redirects on your site to 301s because they pass “link equity” in Google. There is the simple and neat solution for search engine optimization, and it could be plain wrong. At the risk of diverging from the consensus in your favorite discussion forum or offending your SEO consultant, read on and decide for yourself.
Redirects instruct browsers and search engine crawlers that content is available under a different URL. They often go unnoticed as we access Websites. Along with the new location of the content, the server also sends a response code indicating the type of redirect. From an SEO perspective, you generally care about two response codes, 301 Moved permanently and 302 Found:
Let's summarize the effects of the two most common redirect status codes again:
The 301 redirect response is appropriate for the following scenarios:
When Google introduced the “canonical” meta tag in February 2009, this suddenly made sense. Once multiple URLs are known to refer to the same page, or a slight variation of a page, the index only needs to keep one instance of the page.
The canonical meta tag helps the webmaster of a site who give search engines a hint about the preferred URL. The canonical meta tag also helps search engines since mapping multiple crawled URLs to the same page and indexing it only once just became easier.
Whether link equity fully transfers between multiple URLs mapped to the same page remains to be seen. At least within the same domain, this unification process may allow keeping the vanity URL in the index with a 302 redirect response while still transferring link equity.
PS. For an excellent and detailed description how redirects work, how to configure your Web server and what each status code does, see Sebstian's pamphlet The anatomy of a server sided redirect: 301, 302 and 307 illuminated SEO wise.
Redirects instruct browsers and search engine crawlers that content is available under a different URL. They often go unnoticed as we access Websites. Along with the new location of the content, the server also sends a response code indicating the type of redirect. From an SEO perspective, you generally care about two response codes, 301 Moved permanently and 302 Found:
- 301 Moved permanently indicates that the resource has been assigned a different URL permanently, and the original URL should no longer be used. What this means for Search engines is that should index the new URL only. Google also transfers full link equity with a 301 redirect, which is the very reason why you will often see the advice to use 301 redirects.
- 302 Found indicates that the originally requested URL is still valid, and should continue to be used. Search engines vary in how they treat 302 redirects and which URL they show in search result pages, but generally will continue to crawl the original URL as recommended in the HTTP/1.1 specification: “The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests.”
Choosing the right redirect response code
So which redirect response code should you use? Matt Cutts' description how Google treats on-domain and off-domain 302 redirects covers the basic principles and the heuristics that Google used at the time, which to a large extent still apply.Let's summarize the effects of the two most common redirect status codes again:
- 301 redirects transfer link equity to the new URL.
- 301 redirects remove the original URL from the search index.
- 302 redirects often keep the original URL in the index.
The 301 redirect response is appropriate for the following scenarios:
- Content has moved to a different location permanently, for example to a different server name or a different directory structure of the same server. This may be triggered by the rebranding of content where you want all references to the original content to disappear.
- A Website is accessible under multiple host names, such as example.com and www.example.com, or typo catchers like eggsample.com and example.org, but only one name should be indexed.
- A temporary campaign URL is published in direct mail or print advertising, but the landing page has a different permanent URL that will remain accessible beyond the lifetime of the campaign.
- The requested URL does not match the canonical URL for the resource. Often extraneous session and tracking parameters can be stripped, or path information gets added to help with search rankings, for example http://www.amazon.com/Software-
Development- Principles- Patterns- Practices/dp/0135974445
- The original URL is shorter, prettier, more meaningful, etc. and therefore should show on the search engine results page.
- Temporary session or tracking information gets added to the canonical URL. Those URL parameters should not be indexed since they will not apply to other visitors.
- Multiple load balanced servers deliver the content. Indexing an individual server would defeat the purpose of using load balancing. (There are better ways to load balance than having multiple server names, though.)
The “canonical” meta tag
How can you keep the short URL in the index and still transfer link equity? In summer 2008, we started observing that Google somehow “merged” related URLs and treated them as a single entity, showing identical page rank and identical number of inbound links to all of the URLs.When Google introduced the “canonical” meta tag in February 2009, this suddenly made sense. Once multiple URLs are known to refer to the same page, or a slight variation of a page, the index only needs to keep one instance of the page.
The canonical meta tag helps the webmaster of a site who give search engines a hint about the preferred URL. The canonical meta tag also helps search engines since mapping multiple crawled URLs to the same page and indexing it only once just became easier.
Whether link equity fully transfers between multiple URLs mapped to the same page remains to be seen. At least within the same domain, this unification process may allow keeping the vanity URL in the index with a 302 redirect response while still transferring link equity.
PS. For an excellent and detailed description how redirects work, how to configure your Web server and what each status code does, see Sebstian's pamphlet The anatomy of a server sided redirect: 301, 302 and 307 illuminated SEO wise.
Labels: networking, seo, webdevelopment
Wednesday, June 24, 2009
Disagreeing with Jakob Nielsen on security—Password masking makes logins more secure
When it comes to usability, disagreeing with Jakob Nielsen is usually not an option. After all, he has been called king, czar, guru or Web usability for a reason, and his Alertbox offers invaluable advise most of the time.
Disagreeing with Jakob Nielsen on security is easier, especially when he advocates to remove password masking as a means to improve usability and claims that this doesn't lower security.
While not offering a high degree of protection, the password masking does a pretty good job for most situations. Certainly, a determined and skilled criminal would be able to observe which keys are pressed, or use other attack vectors to intercept my Web interactions. I am often surrounded by trustworthy people who still shouldn't know my passwords, don't care about my passwords and even politely turn their eyes away while I am logging in. Whether showing someone a Website or doing a demo to a larger audience, accessing protected areas of a site in a semi-public environment like a desk-sharing area at work or logging in from a mobile device, those little stars or dots protect my passwords well from becoming exposed.
Security and usability should not be conflicting objectives; in fact usability is an important aspect for any security system, or users will work around usability issues and use it in unintended ways, like copying and pasting passwords from a text file as Nielsen mentions. An extra checkbox to enable password masking just adds complexity to the user interface and may confuse users more than not being able to see their password.
Typing passwords on mobile devices (or foreign keyboards, for that matter) can be challenging. Some smartphones like the iPhone or the Nokia N95 show the letter as typed but then quickly replacing it with an asterisk, which is a reasonable compromise.
Instead of cluttering Web forms with additional checkboxes, web developers should demand that browsers and mobile devices provide an option to remove password masking when desired by the user. This would maintain the current level of security by not exposing the passwords to people looking over users' shoulders and address the usability issue for those who have difficulty typing their password and would benefit from visual feedback.
Until then, use this JavaScript bookmarklet to unmask password fields as needed:
(all on one line, or simply drag the Unmask passwords bookmarklet link to your bookmarks).
PS. More ways to reveal passwords in a controlled manner can be found in Martin Brinkmann's blog post Reveal your saved Passwords in Firefox.
Disagreeing with Jakob Nielsen on security is easier, especially when he advocates to remove password masking as a means to improve usability and claims that this doesn't lower security.
While not offering a high degree of protection, the password masking does a pretty good job for most situations. Certainly, a determined and skilled criminal would be able to observe which keys are pressed, or use other attack vectors to intercept my Web interactions. I am often surrounded by trustworthy people who still shouldn't know my passwords, don't care about my passwords and even politely turn their eyes away while I am logging in. Whether showing someone a Website or doing a demo to a larger audience, accessing protected areas of a site in a semi-public environment like a desk-sharing area at work or logging in from a mobile device, those little stars or dots protect my passwords well from becoming exposed.
Security and usability should not be conflicting objectives; in fact usability is an important aspect for any security system, or users will work around usability issues and use it in unintended ways, like copying and pasting passwords from a text file as Nielsen mentions. An extra checkbox to enable password masking just adds complexity to the user interface and may confuse users more than not being able to see their password.
Typing passwords on mobile devices (or foreign keyboards, for that matter) can be challenging. Some smartphones like the iPhone or the Nokia N95 show the letter as typed but then quickly replacing it with an asterisk, which is a reasonable compromise.
Instead of cluttering Web forms with additional checkboxes, web developers should demand that browsers and mobile devices provide an option to remove password masking when desired by the user. This would maintain the current level of security by not exposing the passwords to people looking over users' shoulders and address the usability issue for those who have difficulty typing their password and would benefit from visual feedback.
Until then, use this JavaScript bookmarklet to unmask password fields as needed:
for(var i=0;(var a=document.getElementsByTagName("input")[i]);i++){
if(a.getAttribute("type").indexOf("password")!=-1){
a.type="text"
}
}
window.focus();
(all on one line, or simply drag the Unmask passwords bookmarklet link to your bookmarks).
PS. More ways to reveal passwords in a controlled manner can be found in Martin Brinkmann's blog post Reveal your saved Passwords in Firefox.
Labels: technology, usability, webdevelopment
Saturday, May 30, 2009
IE6 DOM weirdness: It was the base and not the comma
I recently hacked a few lines of JavaScript for an online survey. The script looked fairly straightforward and worked well on Firefox in no time.
Fortunately I had just received a new ThinkPad (more about that later) and hadn't upgraded Internet Explorer yet. Testing with IE6, my code failed miserably. Debugging with the indispensable FireBug light tool revealed that a shared library function for accessing meta information didn't return any information. The very same library function was working nicely on the production Web site, though; at least we hadn't heard any complaints, which given the percentage of users accessing our Web site with IE6 was highly unlikely.
Staring at the screen in disbelieve, our resident jQuery guru eventually found the culprit. Unlike with the infamous Undefined is null or not an object problem, it was not an issue with an extra comma this time.
Rather, IE6 seems to get the structure of documents containing a

into this DOM tree:

So the selector which was correctly looking for
Related information:
Fortunately I had just received a new ThinkPad (more about that later) and hadn't upgraded Internet Explorer yet. Testing with IE6, my code failed miserably. Debugging with the indispensable FireBug light tool revealed that a shared library function for accessing meta information didn't return any information. The very same library function was working nicely on the production Web site, though; at least we hadn't heard any complaints, which given the percentage of users accessing our Web site with IE6 was highly unlikely.
Staring at the screen in disbelieve, our resident jQuery guru eventually found the culprit. Unlike with the infamous Undefined is null or not an object problem, it was not an issue with an extra comma this time.
Rather, IE6 seems to get the structure of documents containing a
base tag wrong, making subsequent meta and link elements children of the base element, turning this source
into this DOM tree:

So the selector which was correctly looking for
html > meta would fail in the rare presence of a base tag, such as on a test page created by yours truly. The quick fix was a slightly less efficient selector html meta, and we were once again painfully reminded that IE6 tends to behave differently from current browsers and requires separate testing.Related information:
- Justin Rogers, BASE tag changes in IE 7 with Examples
Labels: javascript, webdevelopment, windows
Wednesday, September 3, 2008
Google Chrome first impressions
Does the world need another Web browser? Probably not, most people are reasonably happy with Firefox (or SeaMonkey), Safari and Internet Explorer, and a wide range of less known specialized browsers.
But then of course it's hard to ignore a new browser when it's launched by Google. Matt Cutts quickly blogged about the Google Chrome announcement and conspiracy theories, and the search engine guessing feature in particular caught my interest.
www.ibm.com has supported OpenSearch for years and it's good to see a browser finally making good use of the OpenSearch description and providing access to custom search engines using keyboard navigation. With the OpenSearch definition for IBM Search enabled, typing ibm.com Green IT selects IBM Search as the preferred engine for that search:

The same can be achieved in Firefox with keywords, albeit not as easily.
Rendering of XML content including RSS news feeds leaves much to be desired. Hopefully Google will add full XML rendering support and integrate a feed reader soon.
Incognito browsing is another neat idea, it won't help much to preserve your privacy but could be useful for testing when you don't want all the test pages to clutter your browser history.
One prerequisite for me using Chrome is support by RoboForm which keeps track of all my accounts and passwords. RoboForm does not work with Safari but hopefully with Chrome being open source will support this browser. Web development tools that work with Chrome will be the other deal breaker.
In the meantime I will continue to experiment with Chrome and see what else Google's latest brainchild has to offer.
But then of course it's hard to ignore a new browser when it's launched by Google. Matt Cutts quickly blogged about the Google Chrome announcement and conspiracy theories, and the search engine guessing feature in particular caught my interest.
www.ibm.com has supported OpenSearch for years and it's good to see a browser finally making good use of the OpenSearch description and providing access to custom search engines using keyboard navigation. With the OpenSearch definition for IBM Search enabled, typing ibm.com Green IT selects IBM Search as the preferred engine for that search:

The same can be achieved in Firefox with keywords, albeit not as easily.
Rendering of XML content including RSS news feeds leaves much to be desired. Hopefully Google will add full XML rendering support and integrate a feed reader soon.
Incognito browsing is another neat idea, it won't help much to preserve your privacy but could be useful for testing when you don't want all the test pages to clutter your browser history.
One prerequisite for me using Chrome is support by RoboForm which keeps track of all my accounts and passwords. RoboForm does not work with Safari but hopefully with Chrome being open source will support this browser. Web development tools that work with Chrome will be the other deal breaker.
In the meantime I will continue to experiment with Chrome and see what else Google's latest brainchild has to offer.
Labels: technology, webdevelopment
Thursday, August 14, 2008
'undefined' is null or not an object
Tracking down a nasty bug in some JavaScript code I wrote has taken me a while. Granted, the actual script was slightly more complex and much longer, and I may be somewhat out of practice too.
This script worked perfectly fine in Firefox, in Seamonkey, even in Opera but failed miserably in Internet Explorer with the not so helpful error message 'undefined' is null or not an object:
Can you see the problem (and why this works in Mozilla)?
This script worked perfectly fine in Firefox, in Seamonkey, even in Opera but failed miserably in Internet Explorer with the not so helpful error message 'undefined' is null or not an object:
var items = [
{id: 'type', condition: !document.referrer},
{id: 'link', condition: !!document.referrer},
];
for (var i=0; i < items.length; i++) {
var item = items[i];
if(typeof(item.condition) == 'undefined' || item.condition) { // Bang!
// do something useful
}
Can you see the problem (and why this works in Mozilla)?
Labels: javascript, webdevelopment
Friday, June 20, 2008
Firefox 3
The Mozilla project released Firefox 3 on June 17 with an attempt to set the world record in software downloads per day.

While I consider raw traffic numbers only mildly useful and the hunt for traffic records somewhat old-fashioned (when IBM did run the Olympics Websites we would report record traffic numbers, and with the technology available back then the numbers were impressive, but that was in the 1990ies) I gladly did my part to set the world record. I mean, how often do you get a chance to be part of a world record, even if your contribution is only 1/8290545.
I even installed Firefox 3 :-) and for most parts have been satisfied with the result. The only complaint I have is that the installation overwrote the previously installed Firefox 2 despite placing the new version in a different directory, and sure enough some extensions were considered incompatible and therefore disabled.
Multiple Internet Explorer versions can coexist on the same machine thanks to the wonderful Multiple IE installer, can we please get an easy and automated way to run multiple versions of Firefox without fiddling with profiles?

While I consider raw traffic numbers only mildly useful and the hunt for traffic records somewhat old-fashioned (when IBM did run the Olympics Websites we would report record traffic numbers, and with the technology available back then the numbers were impressive, but that was in the 1990ies) I gladly did my part to set the world record. I mean, how often do you get a chance to be part of a world record, even if your contribution is only 1/8290545.
I even installed Firefox 3 :-) and for most parts have been satisfied with the result. The only complaint I have is that the installation overwrote the previously installed Firefox 2 despite placing the new version in a different directory, and sure enough some extensions were considered incompatible and therefore disabled.
Multiple Internet Explorer versions can coexist on the same machine thanks to the wonderful Multiple IE installer, can we please get an easy and automated way to run multiple versions of Firefox without fiddling with profiles?
Labels: technology, webdevelopment, windows
Thursday, December 13, 2007
jQuery and Greasemonkey
Now that Fiddler stopped working for me I used Greasemonkey to modify pages on the fly to test some new functionality.
It took me a while to figure out why a global variable which one of the dynamically added scripts created was not visible to my Greasemonkey script. Of course the answer was right there in the Greasemonkey documentation: "As of Greasemonkey 0.6.4, however, user scripts now have their own JavaScript context and execute completely separately from the content document." Fortunately, the document window is also accessible as unsafeWindow, and sure enough that worked.
PS. Michael Baierl pointed out a sample Greasemonkey script to load jQuery before executing functions that depend on jQuery—nice!
It took me a while to figure out why a global variable which one of the dynamically added scripts created was not visible to my Greasemonkey script. Of course the answer was right there in the Greasemonkey documentation: "As of Greasemonkey 0.6.4, however, user scripts now have their own JavaScript context and execute completely separately from the content document." Fortunately, the document window is also accessible as unsafeWindow, and sure enough that worked.
PS. Michael Baierl pointed out a sample Greasemonkey script to load jQuery before executing functions that depend on jQuery—nice!
Labels: javascript, webdevelopment
Tuesday, August 7, 2007
PHONETIC.FON
The amazon.de Web site has had a problem which has bothered me for some time: The search field on the homepage rendered at about half the usual height and text appeared invisible or white on white, so it was impossible to see text:

It wasn't that bad, I am a pretty solid typer and got the search terms right without seeing what I was typing, most of the time; still an inconvenience when trying to modify a search term, especially when the site starting redirecting search responses to addresses that no longer contain the search term, but not bad enough to spend time figuring out what was causing this.
Today one of my colleagues mentioned that he had found a solution to the problem: the PHONETIC.FON file seems to be the culprit, and indeed renaming that file has solved the problem nicely:

(A quick search for PHONETIC.FON sure enough turned up a page Why Do My Fonts in Netscape Navigator Look Funny? in the Netscape Unofficial FAQs.)

It wasn't that bad, I am a pretty solid typer and got the search terms right without seeing what I was typing, most of the time; still an inconvenience when trying to modify a search term, especially when the site starting redirecting search responses to addresses that no longer contain the search term, but not bad enough to spend time figuring out what was causing this.
Today one of my colleagues mentioned that he had found a solution to the problem: the PHONETIC.FON file seems to be the culprit, and indeed renaming that file has solved the problem nicely:

(A quick search for PHONETIC.FON sure enough turned up a page Why Do My Fonts in Netscape Navigator Look Funny? in the Netscape Unofficial FAQs.)
Labels: technology, webdevelopment, windows
Tuesday, June 26, 2007
Security by obscurity
developer.com ran an article about AJAX security, the title of which caught my attention. The suggestions the author makes, however, are either obvious (use a well-tested framework instead of writing your own code) or plain wrong (pretty much the rest of the suggestions). Michael Baierl has commented in detail about what's wrong with this article.
Another unfortunate case of security by obscurity.
Another unfortunate case of security by obscurity.
Labels: security, webdevelopment