• ajax异步请求302


      我们知道,只有请求成功ajax才会进行回调处理,具体状态码为 status >= 200 && status < 300 || status === 304; 这一点通过查看JQuery的源码就可以证实。

    // Cache response headers
    responseHeadersString = headers || "";
    
    // Set readyState
    jqXHR.readyState = status > 0 ? 4 : 0;
    
    // Determine if successful
    isSuccess = status >= 200 && status < 300 || status === 304;//确定请求是否成功.
    
    // Get response data
    if ( responses ) {
        response = ajaxHandleResponses( s, jqXHR, responses );
    }
    
    // Convert no matter what (that way responseXXX fields are always set)
    response = ajaxConvert( s, response, jqXHR, isSuccess );
    
    // If successful, handle type chaining
    if ( isSuccess ) {
    
        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
        if ( s.ifModified ) {
            modified = jqXHR.getResponseHeader("Last-Modified");
            if ( modified ) {
                jQuery.lastModified[ cacheURL ] = modified;
            }
            modified = jqXHR.getResponseHeader("etag");
            if ( modified ) {
                jQuery.etag[ cacheURL ] = modified;
            }
        }
    
        // if no content
        if ( status === 204 || s.type === "HEAD" ) {
            statusText = "nocontent";
    
        // if not modified
        } else if ( status === 304 ) {
            statusText = "notmodified";
    
        // If we have data, let's convert it
        } else {
            statusText = response.state;
            success = response.data;
            error = response.error;
            isSuccess = !error;
        }
    } else {
        // We extract error from statusText
        // then normalize statusText and status for non-aborts
        error = statusText;
        if ( status || !statusText ) {
            statusText = "error";
            if ( status < 0 ) {
                status = 0;
            }
        }
    }

      举个例子来说明,用ajax来实现重定向,ajax异步请求A,A内部重定向到B。

      思考:

      Q1:ajax回调方法是否会被执行?

      Q2:ajax能否重定向?

    var mobile = $("input[name='mobile']").val();
    $.post("/recharge/pay", {mobile:mobile}, function(backData) {
        alert("执行回调");
        alert(backData);
    }).complete(function(xhr) {
        alert("请求状态码:"+xhr.status);
    });
    @RequestMapping(value = "/recharge/m{mobile}",method = RequestMethod.GET)
    public String rechargeB(@PathVariable String mobile, ModelMap model){
        model.put("mobile",mobile);
        return "user/recharge";
    }
    
    @RequestMapping(value = "/recharge/pay",method = RequestMethod.POST)
    public String rechargeA(String mobile){
        String rechargeUrl = "/recharge/m19012345678";
        return "redirect:"+rechargeUrl;
    }

      测试之后发现,回调方法能正常执行,返回的状态码也是200,这里具体是怎么执行的呢?首先,ajax post 请求到/recharge/pay之后,A方法内部进行重定向,这个时候返回的状态码应该是302;其次,A重定向到B之后,执行完成返回的状态码应该是200;回调方法是在B执行完才执行的。通过谷歌浏览器的Network可证实。

      这个问题可参考stackoverflow上的一个回答。

    You can't handle redirects with XHR callbacks because the browser takes care of them automatically. You will only get back what at the redirected location.

      原来,当服务器将302响应发给浏览器时,浏览器并不是直接进行ajax回调处理,而是先执行302重定向——从Response Headers中读取Location信息,然后向Location中的Url发出请求,在收到这个请求的响应后才会进行ajax回调处理。大致流程如下:

    ajax -> browser -> server -> 302 -> browser(redirect) -> server -> browser -> ajax callback

    而在我们的测试程序中,由于302返回的重定向URL在服务器上有相应的处理程序,所以在ajax回调函数中得到的状态码是200。

    所以,如果你想在ajax请求中根据302响应通过location.href进行重定向是不可行的。

      在测试的时候注意一下,如果你指定了ajax的第4个参数dataType(预期服务器返回的数据类型),可能不会触发回调方法,因为这里会先执行重定向,也就是说,重定向后的内容会作为ajax的接口内容来响应,调试时你也能看见backData的内容不是json字符串,而是重定向到B页面的html字符串。其实这个测试示例的流程本身就存在着问题,ajax请求的地址应该只返回数据,而不是重定向。

      另外需要注意的一点是,get、post就是在ajax的基础上进行封装的,只封装了success,并没有封装error方法,所以,只要请求返回的状态码不是200-300,就不会走回调方法,见源码。

    jQuery.each( [ "get", "post" ], function( i, method ) {
        jQuery[ method ] = function( url, data, callback, type ) {
            // shift arguments if data argument was omitted
            if ( jQuery.isFunction( data ) ) {
                type = type || callback;
                callback = data;
                data = undefined;
            }
    
            return jQuery.ajax({
                url: url,
                type: method,
                dataType: type,
                data: data,
                success: callback //只封装了success方法,没有error。
            });
        };
    });

    总结:

      1、ajax主要用于异步请求数据,而不是重定向,它只负责获取数据或处理结果;

      2、只有状态码 status>=200 && status<300 || status==304 ,才被视为success,才会走success的回调方法;

      3、post、get 只封装了ajax的success方法。

     

    参考文献

  • 相关阅读:
    嵌入式成长轨迹27 【Linux应用编程强化】【中嵌第二阶段】【进程管理】
    嵌入式成长轨迹24【Linux应用编程强化】【Linux下的C编程 下】【实例:Linux命令实现】
    纯CSS代码实现翻页
    Adodb.Stream读取和写入UTF8编码的文件
    对c#拆装箱的性能分析(泛型)
    js自动更换图片代码(收藏)
    提高网站可用性的10个小技巧
    分享下我的家乡语言——湘潭话
    解析用户研究
    HTML5 搭建移动Web应用
  • 原文地址:https://www.cnblogs.com/52XF/p/post302.html
Copyright © 2020-2023  润新知