蜡笔love小新 2018-08-29 03:19 采纳率: 0%
浏览 1279
已结题

axios的响应拦截器怎么做二进制拦截

axios的response返回的是数据流,怎么通过相应拦截器拦截变成二进制数据?

  • 写回答

1条回答 默认 最新

  • Msir_Modern 2018-08-29 04:03
    关注

    首先还是从调用方法开始看:

    var CancelToken = axios.CancelToken;
    var source = CancelToken.source();
    axios.get('/user/12345', {
    cancelToken: source.token
    }).catch(function(thrown) {
    // something
    });
    // cancel the request (the message parameter is optional)
    source.cancel('Operation canceled by the user.');
    分析上面的这段代码,可以看得出CancelToken.source() 是起最主要作用的,包括它的token和cancel方法。我一开始以为取消请求,会是在拦截器的那条管道上去处理,但是实际上并没有,它是把这取消请求的逻辑放到了 adapter(这里主要分析 xhr.js,也就是浏览器部分) 来处理,而 adapter 会在 dispatchRequest 里引用。

    其实这一部分代码并不多,但是理解起来会有点乱,首先看 lib/adapters/xhr.js 这个文件,截取部分代码:

    if (config.cancelToken) {
    config.cancelToken.promise.then(function onCanceled(cancel) {
    if (!request) {
    return;
    }
    request.abort();
    reject(cancel);
    request = null;
    });
    }
    那么这里出现了一个有趣的东西,就是 config.cancelToken,和在第二行代码中的 config.cancelToken.promise,这里的代码我们暂时就简单地理解成当执行了请求取消时,请求会被终止,并且 reject。

    那现在我们去看 cancel 的内部代码,只有 3 个 js 文件,都在 lib/cancel 文件夹里,然后里面最重要的是 CancelTOken.js 文件,代码不多:

    function CancelToken(executor) {
    // 省略...
    var resolvePromise;
    this.promise = new Promise(function promiseExecutor(resolve) {
    resolvePromise = resolve;
    });
    var token = this;
    executor(function cancel(message) {
    if (token.reason) {
    return;
    }
    token.reason = new Cancel(message);
    resolvePromise(token.reason);
    });
    }
    那么从这里,我们看到了 this.promise 这个方法,和上面提到的那个其实是同一个,但是这里,它却没有执行 resolve,而是进行了一个变量赋值。而这个 resolve 是要在 executor 函数传入的函数方法执行的时候,才会被执行,并且返回 reason 信息。

    那其实到了这里,我们还是得从调用方式反过来推导,到现在 token 和 cancel 方法还没出现呢,请看下面的代码:

    CancelToken.source = function source() {
    var cancel;
    var token = new CancelToken(function executor(c) {
    cancel = c;
    });
    return {
    token: token,
    cancel: cancel
    };
    };
    到这里,就很清晰了,如果调用了 cancel 方法,其实就等同于将上一段代码中的 resolvePromise 给执行了,并且 reason 也会被实例化。然后要注意的是,这里的 token,也就是 config.cancelToken,这里必须是要 cancel 方法执行后,this.promise 才会正式 resolve,不然会一直处于 pending 状态。

    那这时候回到 xhr.js 里的那段代码,就真正的连起来了:

    执行 cancel 方法 -> 生成 reason 信息 -> promise resolve -> request abort
    然后这里还有一点,就是被取消的请求,会在 catch 方法里返回(或者在 then 的第二个方法里返回,但是这个没验证过),是因为在 dispatchRequest 里,在请求准备返回响应时,如果请求被取消了,会 throw 一个错误,而因为都是包在 Promise 里,所以这个异常也是会被捕捉到。

    function throwIfCancellationRequested(config) {
    if (config.cancelToken) {
    config.cancelToken.throwIfRequested();
    }
    }
    而这个 throwIfRequested 方法就是简单地把 reason throw 出来。

    评论

报告相同问题?

悬赏问题

  • ¥15 求chat4.0解答一道线性规划题,用lingo编程运行,第一问要求写出数学模型和lingo语言编程模型,第二问第三问解答就行,我的ddl要到了谁来求了
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果