Wednesday, May 19, 2010

Base Dependency, JavaScript and how parseInt() returns 0

I learned today that the parseInt() function in JavaScript actually has a second parameter that is optional. This second parameter defines the number's base. Thus, you can parse an integer that is binary, octal and hexadecimal. However, if you do not define the base, the parseInt function takes a guess at the base instead of defaulting to decimal.

So, if you have a parseInt('08') or parseInt('09'), the function will return 0. This is because it is guessing that these are octal numbers (based on the 0 in front) and then returns a 0 because they are invalid octal numbers.

The fix is simple, define the base. Use parseInt('08',10) or parseInt('09',10) instead. This blog post helped me and has more info on the matter.

Thursday, May 13, 2010

Hash Changing, detecting the Back button in JavaScript

If you use gmail and you are a web developer, you have probably noticed that they use hash or anchor links (e.g., "example.html#hash") to make your browser's back button very effective. These hash or anchor links were designed to bring your browser to a certain position in a page. Often they are used on help pages or FAQ pages to make the browser window scroll to a certain point. But, interestingly, they can also be used to set certain JavaScript states, when configured properly.

In order to monitor the hash state and determine if the browser's back or forward button were hence used, you must set up a polling loop. It will check the current hash against the last hash. If there is a change it will do something magical (whatever you want to do).
<script type="text/javascript">
/* set defaults */
var curHash = window.location.hash;

/* check for a change in hash (back or forward buttons) */
setInterval(function() {
 if (curHash != window.location.hash) {
  curHash = window.location.hash;
  /* -- do what you need to do when the hash changes! -- */
 }
}, 250);
</script>

The check time is set to 250 ms. But this can be tweaked for your particular needs.

There is rumors that in HTML 5 there will be a hash onchange event. This will really clean up the code, removing the need for polling. Until then, this is the next best thing.

Update 10/28/13 - Side Note: Checkout HTML5's push state for doing cool things like this w/o the hash. You can have the whole URL reflect a change in the DOM without the browser trying to go out and fetch a new web page. Pretty cool stuff. Some JavaScript frameworks like Backbone support both the hash change and the newer push state methods.

Monday, May 3, 2010

PEAR Mail.php - Failed to add recipient (code: 451)

I decided to use the PEAR mailer for a web project in order to send emails through my SMTP server. However, I was getting a strange error:
Failed to add recipient: xxxxx@gmail.com [SMTP: Invalid response code received from server (code: 451, response: Temporary local problem - please try later)]

Yikes! That is not a very helpful error. If the server doesn't know what what the response code means, how am I supposed to? Using SSH, I took a look at the exim_rejectlog located at /var/log and found that my mail server didn't particularly care for the source or 'From' email address.

After a bit of trial and error, it became clear that 'From' address must match the SMTP account's address. It is a nice anti-abuse feature (for shared servers) that I wasn't even aware of.

Anyway, if you get this error, it probably could be a number of things, but be sure to check that your 'From' email address matches the email address of the SMTP account you are using to send the email.

Wednesday, April 28, 2010

Page Loading Speed-Up

I found out today that if you have JavaScript and CSS externally linked in your HTML head, the CSS should come first. This will allow browsers to fetch both external files at the same time. I use JavaScript to do some last minute page styling, depending on some parameters and also found that this helped the page flicker.

On a related note, the Page Speed add-on to Firefox is a handy little tool for determining areas for improvement for a website (that's where I learned of this CSS before JS tip).

Monday, April 19, 2010

Blocking Bots and Crawlers without Blocking Search Engines

If you run any high-traffic websites it becomes apparent rather quickly that there are people out there trying to download your entire website (and there are many more people doing it than you would think). The question is, how do you block users with ill intent without blocking the major search engine bots (i.e., Yahoo, Google & Bing)?

The Google-recommended way is to do a reverse DNS look-up using the IP address. Then double-check the reverse DNS with a normal DNS look-up. The explanation is found here. Note that this code will not work alone. If implemented, all regular visitors will be blocked. You must add some code to count the number of visits from a unique IP address and use this information as well.

How is this done in code? Check out this great PHP solution. (Not sure if Bing uses the old msn search bot domain name or not.)

There is one issue that comes up with an implementation like this. By doing this you are blocking all bots and search engine crawlers which are not in your list. In other words, you are helping ensure that no other search engines can index your site. While it does still allow the major search engines to compete on the same level (at least in terms of your site), it is a bit anti-entrepreneurial and anti-competition because it locks-out small search engines and start-ups.

Friday, April 9, 2010

Random exclamation points inserted into emails

I use PHP mail() to send out emails quite often. I recently found out that if you create your email as one long string without line breaks, you'll get random exclamation points in your emails. I was recently pointed towards RFC 2822 section 2.1.1 for the solution. It appears that no line can be longer than 998 characters without a line break.

How do you fix this? (1) The first way is to base-64 encode the data (best solution for plain text emails to retain long lines). Check out this blog for some info on that. (2) The other, much easier way, is to simply insert line breaks in your email (best solution for HTML emails where long lines are not needed). Add a "\r\n" to the end of each line in your email to make sure you never go over 998 characters.

Monday, April 5, 2010

Microsoft Wireless Keyboard 700 v2.0 - Keystroke Problem

I thought I'd post this real quick in case someone else is experiencing the frustrating problem I was having. I have a Microsoft Wireless keyboard and mouse 700 and it has been driving me up the wall lately. The keyboard would miss keystrokes, would occasionally respond with a repeated keystroke and would otherwise be annoying. I tried replacing the batteries, re-syncing and restarting and nothing helped.

Then, I tried moving the receiver device that plugs into my USB port further away and voilĂ : Here I am typing up a storm without getting stressed. It is nice to have a keyboard that works again. Apparently the USB receiver cannot be within a certain distance from my keyboard... maybe I should have read the instruction manual.

Update (6/23/10): The manual states that the mouse & keyboard should be between 8 inches and 4 feet from the receiver.

Update 2 (8/10/10): I've officially given up on this mouse & keyboard. The mouse drains a fresh pair of AA batteries in about two weeks and the keyboard constantly has connectivity problems. I went back to old-fasioned wired replacements, for now.