This is a problem which comes up time and time again. Every time you add a contact form to a website, you open yourself up to spam attacks. Solving this problem involves striking the right balance between making life easy for the person filling in the form, and the person receiving the spam at the other end.
Adding a test to the form that the user must complete before submitting it is the most resilient way. One of the most popular is reCaptcha which uses imperfectly scanned books to test the user by presenting them with two scanned words. The first word, Captcha knows what it should be and the second word is used to help identify the scan. If enough users provide the same identify the second word, it is promoted to a known word.
Cleverly, this helps translate imperfect book scans as well as providing a robust identity check.
However this can be annoying for users, and will reduce the chance of a user completing the form. This should only be used where the level of security is more important than the volume of submissions you require.
If a bot submits your form it is likely that it will either load your page and then imminently submit the form, or scrape the contents, store it somewhere and at some later date start sending submissions.
By creating an encoded token based upon the time of page creation and sending that though with the form you can get a good idea of whether the user may be real or not. For example I may create a field with the value of
Which is the unix timestamp, divided by the day of the month, to obscure the value and make it difficult for bots to spot a pattern.
When the form is submitted, check that this field is passed though, and if it took less than say, 5 seconds to submit the form after the page loaded or more than 30 minutes, return a form error.
The best solution is probably to use a combination of some of the above techniques, depending on how high profile the form is going to be and the security you require from respondents.
Relying on the same technique for all your sites introduces the inherent danger that once one form is compromised, it’s likely that they all will be. Keeping the bots on their toes is the only way of staying ahead of them.