记录传递参数解析中的一个问题以及解决过程

一个请求访问序列化时候的奇怪问题: 即 axios 的 paramsSerializer 设置问题

两个一样的请求在测试用例中不通过, 跟踪到请求参数的不同

然后继续跟踪, 通过具体调用栈查找到都使用了 axios 进行处理。 怀疑是版本不一样导致的。

然后继续跟踪到使用的方法如下

function buildURL(url, params, paramsSerializer) {
  /*eslint no-param-reassign:0*/
  if (!params) {
    return url;
  }


  var serializedParams;
  if (paramsSerializer) {
    serializedParams = paramsSerializer(params);
  } else if (utils.isURLSearchParams(params)) {
    serializedParams = params.toString();
  } else {
    var parts = [];


    utils.forEach(params, function serialize(val, key) {
      if (val === null || typeof val === 'undefined') {
        return;
      }


      if (utils.isArray(val)) {
        key = key + '[]';
      } else {
        val = [val];
      }


      utils.forEach(val, function parseValue(v) {
        if (utils.isDate(v)) {
          v = v.toISOString();
        } else if (utils.isObject(v)) {
          v = JSON.stringify(v);
        }
        parts.push(encode(key) + '=' + encode(v));
      });
    });


    serializedParams = parts.join('&');
  }


  if (serializedParams) {
    var hashmarkIndex = url.indexOf('#');
    if (hashmarkIndex !== -1) {
      url = url.slice(0, hashmarkIndex);
    }


    url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
  }


  return url;
}

发现其中的一个调用中没有 paramsSerializer 的传入, 至此断案了。 增加 paramsSerializer 的传入.

延伸:

搜索一下官方文档, 对 paramsSerializer 的解释

// `paramsSerializer` is an optional function in charge of serializing `params`
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  }

如果不传递, 会走 axios 默认的简单的方法。
如果传递 qs 或者 jquery.param, 尝试了一下 qs 和 jquery.param 的处理

console.log(Qs.stringify({a: [{b: 2,c:3}]}))
console.log(jQuery.param({a: [{b: 2,c:3}]}))

"a%5B0%5D%5Bb%5D=2&a%5B0%5D%5Bc%5D=3”

即 "a[0][b]=2&a[0][c]=3"

发现是一样的, 如果不传递parse函数, 那么 axios 才进行简单的处理, 如下

function encode(val) {
  return encodeURIComponent(val).
    replace(/%40/gi, '@').
    replace(/%3A/gi, ':').
    replace(/%24/g, '$').
    replace(/%2C/gi, ',').
    replace(/%20/g, '+').
    replace(/%5B/gi, '[').
    replace(/%5D/gi, ']');
}

可以看到, 只是进行了 url encode, 并没有进行太多的处理.

原文地址:https://www.cnblogs.com/asdfq/p/12964970.html