jQuery3 Ajax 跨域获取图片验证码(captcha),调试过程和注意到的细节

使用3中方式尝试获取图片,图片由后端动态生成,后端地址跨域

先上源码:

// 获取图片验证码
function getCaptcha() {
    // 使用xhr实现 ===START===
    /*var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://xxx/captcha/get", true);
    xhr.responseType = "blob";
    // console.log(xhr);
    xhr.withCredentials = true;
    xhr.onload = function() {
        if (this.status == 200) {
            var blob = this.response;
            var img = document.createElement("img");
            img.onload = function(e) {
                window.URL.revokeObjectURL(img.src); 
            };
            img.src = window.URL.createObjectURL(blob);
            $('#verifyCodeImg').attr('src', img.src);
        }
    }
    xhr.onreadystatechange = function() {
        // console.log('>>', xhr.readyState, ',', xhr.status);
    }
    xhr.send();*/
    // 使用xhr实现 ====END====

    // 使用请求静态文件的方式,证明普通请求会带着身份信息(withCredential) ===START===
    $('#verifyCodeImg').attr('src', 'http://xxx/captcha/get?_=' + Math.random());
    // 使用请求静态文件的方式,证明普通请求会带着身份信息(withCredential) ====END====

    // 使用ajax方法,失败了,原因没有加上“Access-Control-Allow-Origin”(猜想后台OPTIONS请求被拦截)===START===
    /*$.ajax({
        url: 'http://xxx/captcha/get',
        type: 'GET',
        dataType: 'binary',
        contentType: 'image/jpeg',
        headers: {
            // 'Content-Type': 'image/jpeg',
            // 'X-Requested-With': 'XMLHttpRequest',
            'Access-Control-Allow-Origin': '*'
        },
        processData: false,
        crossDomain: true,
        xhrFields: {
            withCredentials: true,
            responseType: "blob"
        },
        beforeSend: function(xhr) {
            // xhr.setRequestHeader('Content-Type', 'image/jpeg');
            xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
        },
        success: function(result) {
            var blob = result;
            var img = document.createElement("img");
            img.onload = function(e) {
                window.URL.revokeObjectURL(img.src); 
            };
            img.src = window.URL.createObjectURL(blob);
            $('#verifyCodeImg').attr('src', img.src);
            // if (result.Status != 1) {
            //     myApp.alert(result.Message + '<br/>请检查数据并重试', '失败');
            //     getCaptcha();
            //     window.verifyCodeCD = 0;
            // }
            // // 成功的时候
            // else {
            //     myApp.addNotification({
            //         title: '成功',
            //         message: '已发送短信到手机,请查收'
            //     });
            // }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log(XMLHttpRequest, textStatus, errorThrown);
            errorMsg = "获取图片验证码失败!<br/>错误信息:" + textStatus + "错误码:" + XMLHttpRequest.status + '<br/>请点击图片验证码位置重试';
            myApp.alert(errorMsg, '网络错误');
        }
    });*/
    // 使用ajax方法,失败了,原因没有加上“Access-Control-Allow-Origin”(猜想后台OPTIONS请求被拦截)====END====
}

xhr和直接设置src的形式成功了,并且在调试过程中注意到了直接设置src请求是会带着身份一起传,因为之后验证图片验证码的时候,必须要带着身份传(后台是使用session存储的请求)。

最后一种ajax的代码是错误的,这里的代码我尝试了很多次,之前会报出parseerror的错误,这块儿没仔细看,现在是上边写出的状态。报错:

Failed to load http://xxx/captcha/get: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:9292' is therefore not allowed access.

大概翻译是:

加载url失败:
    预检(preflight)请求的响应未通过访问控制检查:
        被请求资源的头部没有发现'Access-Control-Allow-Origin'。
    所以本地origin不允许访问。

请求的响应截图:

注意红框响应头部确实没有Access-Control-Allow-Origin

后端跟我说,他那边已经针对几种请求加了处理了:

所以现在很奇怪,为什么OPTIONS请求返回的相应头部中不带着允许跨域的标志呢?是被Apache拦截了什么的么……?是我之前对报错理解的不到位么?

有人了解的话,还请不吝赐教 m(_ _)m

哦对了,另一个人写的是这样的

// 先设置了全局的ajax跨域且带cookie
$.ajaxSetup({
	crossDomain: true,
	xhrFields: {
		withCredentials: true
	}
});

// 然后这么做的……
$.ajax({
	type: "GET",
	url: "http://xxx/captcha/get",
	success:function(data){
		$("#imgPic").attr("src", "http://xxx/captcha/get");
	}
})

我的直接给img标签设置src就是受这个启发,才发现原来直接请求就可以,而且还带着身份信息,不过因为要可以手动刷新,所以我加了随机变量在请求上。emmm总觉的这个小哥的代码会请求两次而且由于浏览器缓存的原因不会刷新图片内容呢……不过也米有验证过,有机会再说吧哈哈

转载于:https://my.oschina.net/kidou/blog/2253453

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
采用ajax技术实现的图形验证码,在前端进行验证。验证码信息为图片。每一行代码均有注释,通俗易懂。 实现步骤: 1、创建web工程 2、在jsp页面,编写一个 3、编写一个servlet,在servlet中产生图形验证码 ------------------------------------------------------------ //1、给客户端作出的回应是以图片的方式来回应 response.setContentType("image/jpeg"); //2、创建一个图形缓冲区,用于绘制图形 (宽度,高度,颜色的生成方案) BufferedImage image = new BufferedImage(800,600,BufferedImage.TYPE_INT_RGB); //3、创建一支画笔(图形设备接口)用于绘图 Graphics g = image.getGraphics(); //4、指定图笔的颜色 g.setColor(getColor(200,256)); //5、绘制一个矩形框,作为验证码的背景 g.fillRect(0,0, 800,600); //产生一个输出流,准备把图片以流的方式,输出到客户端 OutputStream out = response.getOutputStream(); //输出在图形缓冲区中,绘制的图片 ImageIO.write(image,"jpg",out); //关闭流 out.close(); //随机生成背景颜色 private Random rd = new Random(); //产生随机数类 public Color getColor(int start,int end){ int r = start+rd.nextInt(end-start); int g = start+rd.nextInt(end-start); int b = start+rd.nextInt(end-start); return new Color(r, g, b);//根据三原色的值,随机在指定范围内,生成一种颜色 } --------------------------------------------------------------------------- 0-120 比较适合文字的颜色 100-200 适合干扰线条的颜色 200-255 适合背景颜色 --------------------------------------------------------------------------- 生成图片中的文字: 1、先编写一个字符串,包含:数字,大小字母 private String s = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 2、在产生背景之后,编写如下代码,产生四个字符(并且,把生成字符,保存在session中,在登录的时候用来做判断) String code=""; //用于保存生成的四个字符 for(int i=0;i<4;i++){ //生成一个随机数,它的取值范围,一定要在s这个字符串的长度范围之内 int index = rd.nextInt(s.length()); //2 //把index作为下标,来取得字符串的中某一个字符 char c = s.charAt(index); //指定文字的颜色----深色段 g.setColor(getColor(0,120)); //创建一个字体 Font f = new Font("隶书",Font.ITALIC|Font.BOLD,60+rd.nextInt(60)); //把字体关联到画笔 g.setFont(f); code+=c; //把生成的字符连接成一个字符串 //把文字输出到图片上 g.drawString(String.valueOf(c), 100+i*80+rd.nextInt(100),200+rd.nextInt(150)); } request.getSession().setAttribute("code",code);//把生成的验证码信息,存储到session中,登录的时候,用来作判断 ------------------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值