动态设置所有请求的标头(React,super-agent)

时间:2018-07-06 16:17:21

标签: javascript reactjs http superagent

我想以一种优雅的方式在所有请求上动态设置Authentication标头。我当前的解决方案使用的是superagent-defaults软件包,但它无法处理动态标头

在下面获取示例代码

superagentWrapper.js

import defaults from 'superagent-defaults';
import localStorage from 'localStorage';

const superagent = defaults();

superagent
  .set('Authorization', `Bearer ${localStorage.getItem('access_token')}`);

export default superagent;

api.js

  import request from '../../../utils/superagentWrapper';

  ExampleAuthenticatedCall: (x) => {
    return new Promise((resolve, reject) => {
      request
     .post(sources.exampleCall())
     .accept('json')
     .set('Content-Type', 'application/json')
     .timeout(40000)
     .send({ exampleCall: "xxx"})
     .end((error, res) => {
        res.body.error ? reject(res.body.error) : resolve(res.body);
     });
    });
  },

所以问题是页面加载时所有api文件都需要我的superAgentWrapper。这意味着只要access_token从未更改(该示例在刷新页面之前可能会多次执行),该示例就可以正常工作。

我在https://www.crowdsync.io/blog/2017/10/16/setting-defaults-for-all-your-superagent-requests/找到了解决此问题的方法。

尽管这可能可行,但理想的解决方案是动态镜像请求库拥有的所有方法,而不是手动定义它们(将来可能会添加/删除新方法,因此这种方法有些脆弱)。

也许有人可以通过使用代理/反射将我指向正确的方向吗?

1 个答案:

答案 0 :(得分:2)

使用标准的superagent,而不是返回相同的请求,而是返回一个生成新请求并从localStorage获取当前令牌的函数:

import request from 'superagent';
import localStorage from 'localStorage';

const superagent = () => request
  .set('Authorization', `Bearer ${localStorage.getItem('access_token')}`);

export default superagent;

用法(请参见request and promises):

import request from '../../../utils/superagentWrapper';

AuthenticatedCall: (x) => request() // generate a new request
  .get(sources.AuthenticatedCall(x)) // a request returns a promise by default

如果您不希望将包装器转换为函数,则可以将proxyget handler一起使用。每当被调用时,代理都会使用当前令牌生成一个新请求:

import request from 'superagent';
import localStorage from 'localStorage';

const handler = {
  get: function(target, prop, receiver) {
    return request
      .set('Authorization', `Bearer ${localStorage.getItem('access_token')}`)[prop];
  }
};

const requestProxy = new Proxy(request, handler);

export default requestProxy;

用法(请参见request and promises):

import request from '../../../utils/superagentWrapper';

AuthenticatedCall: (x) => request // generate a new request
  .get(sources.AuthenticatedCall(x)) // a request returns a promise by default