## ajax

基于`Promise`的`ajax`实现，支持browser和node环境，`jsonp`不支持node。

除了axios外，不依赖其他第三方库。

使用时请确保存在全局的`Promise`实现。

## API

`ajax(ajaxOptions, config?): Promise`

`ajaxOptions`是请求的参数，`config`是函数内部的一些可选配置。返回值是一个`Promise`，请求成功会`resolve`，请求失败会
`reject`。

#### 请求成功时`resolve`的结果：

```js
{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the server response
  status: 200,

  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',

  // `headers` the headers that the server responded with
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {}
}
```

#### 请求失败时`reject`的结果:

```js
ajax({ url: '/user/1' })
    .catch(function (error) {
        if (error.response) {
            // The request was made, but the server responded with a status code
            // that falls out of the range of 2xx
            console.log(error.response.data);
            console.log(error.response.status);
            console.log(error.response.headers);
        } else {
            // Something happened in setting up the request that triggered an Error
            console.log('Error', error.message);
        }
    });
```

#### `ajax`请求参数

> ⚠️ 支持部分 `axios` 参数的透传，但是请注意 `axios` 提供的能力不作为这个包的能力。如果今后替换底层的 ajax 实现，这些参数很可能就会失效。

* **`url`**: <`string`> 请求的地址
* **`method` / `type`**: <`string`> 请求的类型，默认`GET`请求
* **`data`**: <`any`> HTTP请求的参数，`GET` / `HEAD`类请求会作为URL参数，`POST` / `PUT`等请求会作为`body`
* **`contentType`**: <`string`> 发送给服务器的数据类型，`POST` / `PUT`等请求默认值为* `'application/x-www-form-urlencoded; charset=UTF-8'`
* **`dataType`**: <`string`> 请求的返回值类型，默认`json`，可选项`arraybuffer`, `blob`, `document`, `json`, * `text`, `stream`
* **`headers`**: <`object`> HTTP请求的头，`'X-Requested-With': 'XMLHttpRequest'`一定会加上。
* **`withCredentials`**: <`bool`> 默认`false`, indicates whether or not cross-site Access-Control requests should be made using credentials
* **`username`**: <`string`> HTTP请求的用户名
* **`password`**: <`string`> HTTP请求的密码
* **`timeout`**: <`number`> 请求的超时时间，`0`表示没有超时
* **`noXRequestedWithHeader`**: <`bool`> 是否强制加上`X-Requested-With`这个头，这个头会触发CORS preflight，默认 `true`，不加这个头；设为 `false` 的话会强制加上这个头。这个默认值和名字可能感觉很难受，这么做是为了保持向后兼容老代码。
* **`onUploadProgress`**: <`function`> 上传请求的进度回调函数，参数是 progressEvent
* **`onDownloadProgress`**: <`function`> 下载请求的进度回调函数，参数是 progressEvent
* **`cancelToken`**: <`CancelToken`> 用来取消请求的token，具体请看下面的取消请求文档
* **`allowBigNumberInJSON`**: <`bool`> 如果为 `true`，将使用一个自定义的 JSON parser，这个 parser 会将某些大整数或者精度过高的小数会表示成字符串。

#### `jsonp`请求参数

* **`url`**: <`string`> 请求的地址
* **`data`**: <`object` | `FormData`> 请求参数，会序列化到 URL 后面
* **`jsonp`**: <`string`> `JSONP`请求的回调参数名称, `callback=__jp01`中的`callback`部分，默认为`callback`
* **`jsonpCallback`**: <`string`|`function`> `JSONP` 请求的回调函数名，如果是函数则使用函数的返回值，`callback=__jp01`中的`__jp01`部分，默认值是每次请求都生成一个不一样的名字
* **`prefix`**: <`string`> `JSONP` 请求回调函数名字的前缀，`callback=__jp01`中的`__jp`部分，后面的部分会用随机字符串填充
* **`timeout`**: <`number`> 请求的超时时间，`0`表示没有超时
* **`cache`**: <`bool`> 如果设置为`false`，会强制浏览器不缓存请求，默认为`false`

#### `config`

`config.transformRequest(ajaxOptions): ajaxOptions` 接受一个`ajax`请求的参数对象，可以对这个参数做一些处理，
返回值也是一个`ajax`请求的参数。主要用来在发送请求前对参数做一些转换。

#### 取消请求

使用 `ajax` 上的 `CancelToken` 创建 token，有两种使用方式。

> 不同的请求可以使用同一个token，调用这个 token 的 `cancel` 方法时会同时取消所有使用这个 token 的请求。

jsonp 请求不支持取消操作。

```js
var CancelToken = ajax.CancelToken;
var source = CancelToken.source();

ajax({
  url: ''/user/12345',
  cancelToken: source.token
}).catch(function(thrown) {
  if (ajax.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
```

```js
var CancelToken = ajax.CancelToken;
var cancel;

ajax({
  url: '/user/12345',
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();
```

#### 关于URL参数序列化

内部使用的序列化函数等价于`jQuery.param(value, false)`

## Change log

* 3.0.0 升级 axios 到 0.19.0，修复了一个 axios 的一个严重安全漏洞
* 2.1.0 支持部分 axios 参数的透传
* 2.0.0 升级 axios 到 0.18.0
* 1.2.1 修复 `content-type` 头被设置多次的问题。
* 1.2.0 这个版本跨域请求有问题，请不要使用。
