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

为什么80%的码农都做不了架构师?>>>   hot3.png

使用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 + '
请检查数据并重试', '失败'); // getCaptcha(); // window.verifyCodeCD = 0; // } // // 成功的时候 // else { // myApp.addNotification({ // title: '成功', // message: '已发送短信到手机,请查收' // }); // } }, error: function (XMLHttpRequest, textStatus, errorThrown) { console.log(XMLHttpRequest, textStatus, errorThrown); errorMsg = "获取图片验证码失败!
错误信息:" + textStatus + "错误码:" + XMLHttpRequest.status + '
请点击图片验证码位置重试'; 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不允许访问。

请求的响应截图: jQuery3 Ajax 跨域获取图片验证码(captcha),调试过程和注意到的细节_第1张图片

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

后端跟我说,他那边已经针对几种请求加了处理了: jQuery3 Ajax 跨域获取图片验证码(captcha),调试过程和注意到的细节_第2张图片

所以现在很奇怪,为什么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

你可能感兴趣的:(jQuery3 Ajax 跨域获取图片验证码(captcha),调试过程和注意到的细节)