0

我有一个动态生成验证码图像并作为二进制文件返回的操作方法。在我的视图页面上,我能够在页面加载时显示验证码。我还有一个刷新链接,它调用操作方法以使用 $.ajax 获取新的验证码图像,单击该链接时不会显示新的验证码图像。$.jax 调用成功,但二进制文件未显示。单击刷新链接时,我想显示新图像而不重新加载整个页面。

我是否遗漏了某些内容,或者是否有另一种方法可以在不使用 jquery 刷新页面的情况下调用操作方法。任何帮助,将不胜感激。下面是我的代码

// 生成图像的动作方法

public class HomeController : Controller
{
        public FileContentResult CaptchaImage(bool noisy = true)
        {
            var rand = new Random((int)DateTime.Now.Ticks);

            //generate new question
            int a = rand.Next(10, 99);
            int b = rand.Next(0, 9);
            var captcha = string.Format("{0} + {1} = ?", a, b);

            //store answer
            Session["Captcha"] = a + b;

            //image stream
            FileContentResult img = null;

            using (var mem = new MemoryStream())
            using (var bmp = new Bitmap(130, 30))
            using (var gfx = Graphics.FromImage((Image)bmp))
            {
                gfx.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                gfx.SmoothingMode = SmoothingMode.AntiAlias;
                gfx.FillRectangle(Brushes.White, new Rectangle(0, 0, bmp.Width, bmp.Height));

                //add noise
                if (noisy)
                {
                    int i, r, x, y;
                    var pen = new Pen(Color.Yellow);
                    for (i = 1; i < 10; i++)
                    {
                        pen.Color = Color.FromArgb(
                        (rand.Next(0, 255)),
                        (rand.Next(0, 255)),
                        (rand.Next(0, 255)));

                        r = rand.Next(0, (130 / 3));
                        x = rand.Next(0, 130);
                        y = rand.Next(0, 30);

                        gfx.DrawEllipse(pen, x - r, y - r, r, r);
                    }
                }

                //add question
                gfx.DrawString(captcha, new Font("Tahoma", 15), Brushes.Gray, 2, 3);

                //render as Png
                bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Png);
                img = this.File(mem.GetBuffer(), "image/png");
            }

            return File(img.FileContents, img.ContentType);
        }

}

// 查看调用action方法显示验证码的页面

<a id="GetCaptcha" href="javascript:void(0)">Refresh</a>
<img id="CaptchaImg" alt="Captcha" src="@Url.Action("CaptchaImage")" style="" />

@section Scripts{
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        $(function () {
            $('#GetCaptcha').click(function () {                

                $.ajax({
                    type: "GET",
                    url:  '@Url.Action("CaptchaImage")', 
                    contentType: "image/png",
                    success: function (data) {
                        alert("Success"); // For testing
                        $('#CaptchaImg').attr('src', "data:image/png;base64," + data);
                    },
                   error: function(error, txtStatus) {
                            console.log(txtStatus);
                            console.log('error');
                        }
                });
            });
        });

    </script>
}
4

1 回答 1

0

action 方法不会生成 base64 编码的字符串,而是创建完整的文件响应。

因此,要刷新验证码图像,您无需更新现有图像上的源,而是创建一个新<img src="/home/captchaimage?randomString">元素并用它替换现有的验证码图像。

缓存很可能是一个问题,因此您需要生成一个唯一的字符串以附加到路径中,例如随机数或当前日期时间,因此每个请求都是唯一的。

否则,您更改您的操作方法以返回一个 base64 字符串,然后<img src="@Url.Action..将视图中的更改为<img src="data:image/png;base64,@Html.Action(...或类似的东西。

于 2013-09-25T01:29:04.480 回答