code: async function request (url, options) {
    if (!options) {
      if (isPlainObject(url)) {
        options = url
        url = null
      } else {
        options = {
          url
        }
      }
    }
  
    if (!isPlainObject(options)) {
      throw new ParameterException('Options must be an object!')
    }
  
    if (isString(url)) {
      options.url = url
    }
  
    if (!isString(options.url)) {
      throw new ParameterException('URL is required!')
    }
  
    let { interceptors, ...req } = options
    interceptors = intercept(interceptors)
  
    req = await parseReq(req)
    req = await iterateInterceptors(req, interceptors.request)
  
    const res = await fetch(req.url, req)
  
    let body = await getBody(res)
    body = await iterateInterceptors(body, interceptors.response)
  
    if (res.status >= 200 && res.status < 400) {
      return body
    }
  
    throw body
  }
docs: request
  
  request({
  url: 'path',
  query: { ... },    //  url 请求参数
  params: { ... },   //  url 宏参值替换
  body: { ... },     //  请求体
  headers: { ... },  //  请求头
  interceptors: {    //  请求和返回体加工函数的数组对象
  request: [func1, func2, ...],
  response: [func1, func2, ...]
  }
  })
  request('path')
  request('path', { ... })
  
  @param  {string} [url]       URL
  @param  {object} [options]   Options
  @return {promise}            Promise