Often times you do not need the whole deal, or you are working with a technology that doesn't employ javascript or iframes
Recently I was working on a project that needed to provide (via MVC 3) the ReCaptcha image and/or challenge key only, and not the whole html/javascript portion due to limitations by the data consumer. It took me a while, but there is quite an elegant and simple solution to this.
Here is the controller I came up with:
public class CaptchaController : Controller
{
public string contentReturnType = "text/plain";
public string googleChallengeUrl = "http://
www.google.com/recaptcha/api/challenge?k={0}";
public string googleImageUrl = "http://
www.google.com/recaptcha/api/image?c={0}";
public string googleImageHtml = "<img style=
\"display: block; \" height=\"57\" width=\"300\"
src=\"{0}\"/>";
[HttpGet]
public ContentResult GetChallengeKey(
string proxyIpAndPort = null)
{
string http = string.Format(googleChallengeUrl,
ReCaptchaValues.PublicKey);
WebClient client = new WebClient();
//assuming no proxy on a local machine
if (!string.IsNullOrEmpty(proxyIpAndPort) &&
!Request.IsLocal)
{
client.Proxy =
new WebProxy(proxyIpAndPort, true);
}
string html = client.DownloadString(http);
int start = html.IndexOf('{');
int length = html.IndexOf('}') - start + 1;
string json = html.Substring(start, length);
ReCaptchaState state =
new JavaScriptSerializer()
.Deserialize(json);
return this.Content(state.challenge,
contentReturnType);
}
[HttpGet]
public ContentResult GetImageUrl()
{
return this.Content(string.Format(googleImageUrl,
GetChallengeKey().Content), contentReturnType);
}
[HttpGet]
public ContentResult GetImageHtml()
{
return this.Content(string.Format(googleImageHtml,
GetImageUrl().Content), contentReturnType);
}
}
This is using json deserializing of the ReCaptcha return string into a .Net object named ReCaptchaState which is covered here.
Now all that you need to do is call one of the urls to get the desired result in a plaintext format (you can change the output if you wish).