zoukankan      html  css  js  c++  java
  • 当jquery ajax遇上401请求

    jquery ajax是个很常用接口,而在请求时候,可能存在响应401的情况(身份认证过期或未登录),比较容易出现在混合应用上,如何进行身份认证,重发失败请求,还是值得注意的。

    ajax请求有两种方式

    1. 回调

    最常写的方式,成功失败处理以回调方式传入。

    $.ajax({
          ajax参数...
          success : xxxxxx
          error: xxxxxx
    });

    2. Deferred方式

    Deferred模式我在《js异步编程》有说明, ajax调用本身返回就是一个Deferred对象,成功失败回调不以参数传入。

    $.ajax({
         ajax参数...
    }).then(function(res){
        //成功处理片段
    },function(err){
        //失败处理片段
    });

    既然有这两种方式,那应对处理401的方式也是有两种。

    401处理的两种方式

    1. 回调

    这种方式的处理比较简单,在失败回调里面判断401,如果是则进行身份认证,成功重发请求。

    function  getXXXX(type, url, data, success, error){
      $.ajax({
          ajax参数...
          success : xxxxxx
          error : function(xhr,textStatus,errorThrown){
             if (xhr.status == 401) {
                刷新身份认证方法(function(){
                    getXXXX(type, url, data, success, error);
                 });
              } else{
                 // 调用外部的error
                  error && error(xhr,textStatus,errorThrown);
             }
          }
      });
    }

    2. Deferred方式

    这种方式目前我找到的处理方式需要修改jquery源码。

    //全局设置一个方法
    $.ajaxSetup({
         authError : function(callback){
               刷新身份认证方法( function(){
                    callback && callback();
               });
         }
    });
     
    //jquery2.1.4版本源码,大概是8261行
    // Success/Error
    if ( isSuccess ) {
         deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
    } else {
         if(( jqXHR.status == 401 || jqXHR .status == 403) && callbackContext.authError){
           callbackContext.authError(function (){
                state = 0;
                jqXHR.setRequestHeader( "Authorization", XXXXXX);
                jqXHR.readyState = 1;
                try {
                    state = 1;
                    transport.send( requestHeaders, done );
                } catch ( e ) {
                    // Propagate exception as error if not done
                    if ( state < 2 ) {
                         done( -1, e );
                    // Simply rethrow otherwise
                    } else {
                        throw e;
                    }
                }
           });
           return;
         } else {
               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
         }
    }

    这里说下为什么不能像第一种方式那样进行请求。

    有两个原因:

    1. then这种链式写法,导致这请求的回调不是在参数里,而是在jQuery.Callbacks一个optionsCache全局变量里,我们无法在ajax error里拿到回调函数进行重发。

    2. 写在then里的回调触发一次就会被销毁,当触发了error时,回调执行后就销毁。

    最后的处理方式就是在要触发error之前,拦截401的错误,重新进行身份认证,然后重置状态,重发请求。

    本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。
  • 相关阅读:
    NetSuite Batch Process Status
    NetSuite generated bank files and the Bank Reconciliation process
    Global Search file content in Gitlab repositories, search across repositories, search across all files
    FedEx Package Rate Integration with NetSuite direct integrate by WebServices
    git Merge branches
    git tag and NetSuite deployment tracking
    API 读写cookie的方法
    C# 生成缩略图
    解决jquery操作checkbox全选全不选无法勾选问题
    JS读取写入删除Cookie方法
  • 原文地址:https://www.cnblogs.com/lovesong/p/5402092.html
Copyright © 2011-2022 走看看