https://github.com/chinanf-boy/got-zh
中文翻译: <got> 简化的HTTP请求 :heart: 校对 ✅
https://github.com/chinanf-boy/got-zh
docs got http zh
Last synced: 3 months ago
JSON representation
中文翻译: <got> 简化的HTTP请求 :heart: 校对 ✅
- Host: GitHub
- URL: https://github.com/chinanf-boy/got-zh
- Owner: chinanf-boy
- Created: 2018-11-12T05:30:20.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-03-29T04:57:15.000Z (about 7 years ago)
- Last Synced: 2025-10-20T10:36:54.339Z (8 months ago)
- Topics: docs, got, http, zh
- Size: 57.6 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# sindresorhus/got [![explain]][source] [![translate-svg]][translate-list]
[explain]: http://llever.com/explain.svg
[source]: https://github.com/chinanf-boy/Source-Explain
[translate-svg]: http://llever.com/translate.svg
[translate-list]: https://github.com/chinanf-boy/chinese-translate-list
[size-img]: https://packagephobia.now.sh/badge?p=Name
[size]: https://packagephobia.now.sh/result?p=Name
「 简化的HTTP请求 」
[中文](./readme.md) | [english](https://github.com/sindresorhus/got)
---
## 校对 ✅
翻译的原文 | 与日期 | 最新更新 | 更多
---|---|---|---
[commit] | ⏰ 2018-11-08 | ![last] | [中文翻译][translate-list]
[last]: https://img.shields.io/github/last-commit/sindresorhus/got.svg
[commit]: https://github.com/sindresorhus/got/tree/7f18ef397341214d9f46d774f69e65d6cdd95494
### 贡献
欢迎 👏 勘误/校对/更新贡献 😊 [具体贡献请看](https://github.com/chinanf-boy/chinese-translate-list#贡献)
## 生活
[If help, **buy** me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰](https://github.com/chinanf-boy/live-need-money)
---
> 简化的HTTP请求
[](https://travis-ci.org/sindresorhus/got) [](https://coveralls.io/github/sindresorhus/got?branch=master) [](https://npmjs.com/got) [](https://packagephobia.now.sh/result?p=got)
Got是一个人性化,且功能强大的HTTP请求库.
它的创建是因为常用的[`request`](https://github.com/request/request)包过臃肿: [](https://packagephobia.now.sh/result?p=request)
Got是Node.js的请求库。对于浏览器的请求,我们建议[ky](https://github.com/sindresorhus/ky).
## Highlights
- [x] [Promise 和 Streams API](#api)
- [x] [请求取消](#aborting-the-request)
- [x] [符合RFC的缓存](#cache-adapters)
- [x] [遵循重定向](#followredirect)
- [x] [失败时重试](#retry)
- [x] [进展事件](#onuploadprogress-progress)
- [x] [处理 gzip/deflate](#decompress)
- [x] [超时处理](#timeout)
- [x] [元数据错误](#errors)
- [x] [JSON模式](#json)
- [x] [WHATWG URL支持](#url)
- [x] [钩子](https://github.com/sindresorhus/got#hooks)
- [x] [具有自定义默认值的实例](#instances)
- [x] [可组合](advanced-creation.zh.md#merging-instances)
- [x] [Electron支持](#useelectronnet)
- [由~2000包和~500K repos使用](https://github.com/sindresorhus/got/network/dependents)
- 积极维护
[了解Got,如何与其他HTTP库进行比较](#comparison)
## Install
```
$ npm install got
```
## Usage
```js
const got = require('got');
(async () => {
try {
const response = await got('sindresorhus.com');
console.log(response.body);
//=> ' ...'
} catch (error) {
console.log(error.response.body);
//=> 'Internal server error ...'
}
})();
```
###### Streams
```js
const fs = require('fs');
const got = require('got');
got.stream('sindresorhus.com').pipe(fs.createWriteStream('index.html'));
// For POST, PUT, and PATCH methods `got.stream` returns a `stream.Writable`
fs.createReadStream('index.html').pipe(got.stream.post('sindresorhus.com'));
```
### API
`GET`方法为默认情况下的请求,但可以使用不同的方法,或在`options`.
#### got(url, [options])
- 返回一个[`response`对象](#response)的Promise或者
- 一个[stream](#streams-1),如果`options.stream`设置为true.
参数 |
---|
[url](#url) |
[options](#options) |
##### url
类型: | `string` `Object`
---|---
- 请求的URL,若是字符串, 一个[`https.request`选项对象](https://nodejs.org/api/https.html#https_https_request_options_callback)或者一个[WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url).
- `options`的属性将覆盖这个`url`属性.
- 如果未指定协议,则默认为`https`.
##### options
类型: | `Object`
---|---
参数 |> [Streams](#streams) / [baseUrl](#baseurl) / [headers](#headers) / [stream](#stream) / [body](#body) / [cookieJar](#cookiejar) / [encoding](#encoding) / [form](#form) / [json](#json) / [query](#query) / [timeout](#timeout) / [retry](#retry) / [followRedirect](#followredirect) / [decompress](#decompress) / [cache](#cache) / [request](#request) / [useElectronNet](#useelectronnet) / [throwHttpErrors](#throwhttperrors) / [agent](#agent) / [hooks](#hooks)
任何一个[`https.request`](https://nodejs.org/api/https.html#https_https_request_options_callback)的选项.
###### baseUrl
类型:| `string` `Object`
---|---
- 指定时,`baseUrl`将作为`url`的前缀.
如果您指定绝对URL,它将跳过`baseUrl`。
使用`got.extend()`时非常有用,用于创建利基特定的Got实例.
可以是字符串或[WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url).
削减`baseUrl`的结尾,拼接开始的`url`参数,且是可选的:
```js
await got('hello', {baseUrl: 'https://example.com/v1'});
//=> 'https://example.com/v1/hello'
await got('/hello', {baseUrl: 'https://example.com/v1/'});
//=> 'https://example.com/v1/hello'
await got('/hello', {baseUrl: 'https://example.com/v1'});
//=> 'https://example.com/v1/hello'
```
###### headers
类型:| `Object`
---|---
默认:|`{}`
请求标头.
- 现有标题将被覆盖。标题设置为`null`将被省略.
###### stream
类型:| `boolean`
---|---
默认:|`false`
返回一个`Stream`,而不是`Promise`。这相当于调用`got.stream(url, [options])`.
###### body
类型:| `string` `Buffer` `stream.Readable` [`form-data`实例](https://github.com/form-data/form-data)
---|---
*如果您提供此选项,`got.stream()`将是只读的.*
`POST`请求发送的主体.
如果存在`options`和`options.method`未设定,`options.method`将被设置为`POST`.
该`content-length`标题将自动设置,如果`body`是一个`string`/`Buffer`/`fs.createReadStream`实例/[`form-data`实例](https://github.com/form-data/form-data),和`content-length`和`transfer-encoding`就不再是`options.headers`的手动设置.
###### cookieJar
类型: | [`tough.CookieJar`实例](https://github.com/salesforce/tough-cookie#cookiejar)
---|---
Cookie支持.您不必关心解析或如何存储它们.[例子.](#cookies)
**注意:** `options.headers.cookie`将被覆盖.
###### encoding
类型:| `string` `null`
---|---
默认: | `'utf8'`
[编码-Encoding](https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings)用于响应数据的`setEncoding`。如果`null`, 响应body会返回一个[`Buffer`](https://nodejs.org/api/buffer.html)(二进制数据).
###### form
类型:| `boolean`
---|---
默认: | `false`
*如果您提供此选项,`got.stream()`将是只读的.*
如果设置为`true`和`Content-Type`标头未设置,它将被设置为`application/x-www-form-urlencoded`.
`body`必须是一个普通的对象。它将使用[`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj)转换为查询字符串.
###### json
类型:| `boolean`
---|---
默认: | `false`
*如果你使用`got.stream()`,此选项将被忽略.*
如果设置为`true`和`Content-Type`标头未设置,它将被设置为`application/json`.
用`JSON.parse`解析响应主体,并设置`accept`标题为`application/json`。如果与`form`选项一起使用,`body`将字符串化为查询字符串,并将响应解析为JSON.
`body`必须是普通对象或数组,和能对其进行字符串化.
###### query
类型: | `string` `Object` [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
---|---
添加到请求URL的查询字符串。这将覆盖`url`的查询字符串.
如果你需要传入一个数组,你可以使用一个`URLSearchParams`,例如:
```js
const got = require('got');
const query = new URLSearchParams([['key', 'a'], ['key', 'b']]);
got('https://example.com', {query});
console.log(query.toString());
//=> 'key=a&key=b'
```
如果你需要一个不同的数组格式,你可以使用[`query-string`](https://github.com/sindresorhus/query-string)包:
```js
const got = require('got');
const queryString = require('query-string');
const query = queryString.stringify({key: ['a', 'b']}, {arrayFormat: 'bracket'});
got('https://example.com', {query});
console.log(query);
//=> 'key[]=a&key[]=b'
```
###### timeout
类型:| `number` `Object`
---|---
在中止请求发生[`got.TimeoutError`](#gottimeouterror)错误(a.k.a.`request`属性)之前,等待服务器结束响应的毫秒数。默认情况下,没有超时.
这也会接受`object`,使用以下字段来约束请求生命周期的每个阶段的持续时间:
- `lookup`在分配套接字时启动,在解析主机名时结束。使用Unix域名套接字时不适用.
- `connect`从`lookup`完成开始(或如果lookup不适用于请求,分配套接字的时候),并在连接套接字时结束.
- `secureConnect`从`connect`完成时开始,和在握手过程完成后结束(仅限HTTPS).
- `socket`在连接套接字时开始。看[request.setTimeout](https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback).
- `response`当请求已写入套接字时开始,并在收到响应头时结束.
- `send`套接字连接时开始,并以请求结束写入套接字.
- `request`在请求初始化后开始,在响应的结束事件触发时结束.
###### retry
类型:| `number` `Object`
---|---
默认: | 重试:`2`次
方法: | `GET` `PUT` `HEAD` `DELETE` `OPTIONS` `TRACE`
statusCodes: | [`408`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) [`413`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) [`429`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) [`500`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) [`502`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) [`503`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) [`504`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504)
maxRetryAfter: | `undefined`
- Object对象 : 代表
- `retries`, 重试
- `methods`, 允许的方法
- `statusCodes`和
- `maxRetryAfter` 最大[`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After)时间。
如果`maxRetryAfter`被设置为`undefined`,它会用`options.timeout`.
如果[`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After)标头大于`maxRetryAfter`,它将取消请求.
重试之间的延迟计算是`1000 * Math.pow(2, retry) + Math.random() * 100`函数,这里的`retry`是尝试数(从1开始).
`retries`属性可以
- 是`number`或者
- 一个带`retry`和`error`参数的`function`.该函数必须以毫秒为单位的延迟返回(返回`0`值,会取消重试).
**注意:**它仅在指定的方法,状态代码和这些网络错误上重试:
- `ETIMEDOUT`: 达到[超时](#timeout)其中一个限制.
- `ECONNRESET`:连接被网络点强行关闭.
- `EADDRINUSE`:无法绑定到任何自由端口.
- `ECONNREFUSED`:连接被服务器拒绝.
- `EPIPE`:正在写入的流的远程端已关闭.
- `ENOTFOUND`:无法将主机名解析为IP地址.
- `ENETUNREACH`: 没有网络连接.
- `EAI_AGAIN`:DNS查找超时.
###### followRedirect
类型:| `boolean`
---|---
默认:|`true`
定义是否应自动遵循重定向响应.
请注意,如果服务器发送回来一个`303`,以响应任何请求类型(`POST`,`DELETE`等等),Got会自动通过`GET`请求,位置头中指向的资源。这符合[规范](https://tools.ietf.org/html/rfc7231#section-6.4.4).
###### decompress
类型:| `boolean`
---|---
默认:|`true`
自动解压响应。这将设置`accept-encoding`标题为`gzip, deflate`,除非你自己设定.
如果禁用此选项,则会将压缩响应作为一个`Buffer`返回。如果您想自己处理解压或stream式处理原始压缩数据, 这可能很有用.
###### cache
类型:| `Object`
---|---
默认:|`false`
[缓存适配器实例](#cache-adapters)用于存储缓存的数据.
###### request
类型:| `Function`
---|---
默认: | `http.request` `https.request` *(取决于协议)*
自定义请求函数.这样做的主要目的是为了[通过包装HTTP2,以此支持这个协议](#experimental-http2-support).
###### useElectronNet
类型:| `boolean`
---|---
默认:|`false`
在Electron中使用时,Got会使用[`electron.net`](https://electronjs.org/docs/api/net/)替代Node.js`http`模块。根据Electron的文档,它应该是完全兼容的,但其实不是完全兼容.看到[#443](https://github.com/sindresorhus/got/issues/443)和[#461](https://github.com/sindresorhus/got/issues/461).
###### throwHttpErrors
类型:| `boolean`
---|---
默认:|`true`
确定是否抛出`got.HTTPError`错误响应(非2xx状态代码).
如果禁用此选项,在请求遇到错误状态代码,会使用`response` resolve,而不是抛出`got.HTTPError`。如果您正在检查资源可用性,并且期望出现错误响应,这可能很有用.
###### agent
对应`http.request`的[`agent`选项](https://nodejs.org/api/http.html#http_http_request_url_options_callback),但有一个额外的功能:
如果您需要针对不同协议的不同代理,则可以将代理映射传递给`agent`选项。这是必要的,因为对一个协议的请求可能会重定向到另一个协议。在这种情况下,Got将为您切换到正确的协议代理.
```js
const got = require('got');
const HttpAgent = require('agentkeepalive');
const {HttpsAgent} = HttpAgent;
got('sindresorhus.com', {
agent: {
http: new HttpAgent(),
https: new HttpsAgent()
}
});
```
###### hooks
类型:| `Object`
---|---
钩子允许在请求生命周期中进行修改。钩子函数可以是异步的,和也能串行运行的.
###### hooks.beforeRequest
类型:| `Function[]`
---|---
默认:|`[]`
调用[标准的](source/normalize-arguments.js) [请求选项](#options)。在发送请求之前,不会对请求进行进一步更改。这对结合[`got.extend()`](#instances)和[`got.create()`](advanced-creation.zh.md)使用,特别有用,当您想要创建一个API客户端时,例如,使用HMAC签名.
见[AWS部分](#aws)举的例子.
**注意**:如果你修改了`body`,你也需要修改`content-length`标题,因为它已经被计算和分配.
###### hooks.beforeRedirect
类型:| `Function[]`
---|---
默认:|`[]`
调用[标准的](source/normalize-arguments.js) [请求选项](#options)。Got的请求不会进一步更改.当您想要避免死站点时,这尤其有用.例:
```js
const got = require('got');
got('example.com', {
hooks: {
beforeRedirect: [
options => {
if (options.hostname === 'deadSite') {
options.hostname = 'fallbackSite';
}
}
]
}
});
```
###### hooks.beforeRetry
类型:| `Function[]`
---|---
默认:|`[]`
调用[标准的](source/normalize-arguments.js) [请求选项](#options),错误和重试计数。Got的请求不会进一步更改。在下次尝试之前,需要一些额外的工作时,这尤其有用.例:
```js
const got = require('got');
got('example.com', {
hooks: {
beforeRetry: [
(options, error, retryCount) => {
if (error.statusCode === 413) { // Payload too large
options.body = getNewBody();
}
}
]
}
});
```
###### hooks.afterResponse
类型:| `Function[]`
---|---
默认:|`[]`
调用[响应对象](#response)和重试函数.
每个函数都应该返回响应。当您想要刷新访问令牌时,这尤其有用.例:
```js
const got = require('got');
const instance = got.extend({
hooks: {
afterResponse: [
(response, retryWithMergedOptions) => {
if (response.statusCode === 401) { // Unauthorized
const updatedOptions = {
headers: {
token: getNewToken() // Refresh the access token
}
};
// Save for further requests
instance.defaults.options = got.mergeOptions(instance.defaults.options, updatedOptions);
// Make a new retry
return retryWithMergedOptions(updatedOptions);
}
// No changes otherwise
return response;
}
]
},
mutableDefaults: true
});
```
#### Response
响应对象通常是一个[Node.js HTTP响应流](https://nodejs.org/api/http.html#http_class_http_incomingmessage)但是,如果从缓存返回,那它会是一个[类似响应的对象](https://github.com/lukechilds/responselike)和行为方式相同.
**参数** |> [body](#body-1) / [url](#url-1) / [requestUrl](#requesturl) / [timings](#timings) / [fromCache](#fromcache) / [redirectUrls](#redirecturls) / [retryCount](#retrycount) /
##### body
类型:| `string` `Object` *(取决于`options.json`)*
---|---
请求的结果.
##### url
类型:| `string`
---|---
重定向后的请求URL或最终URL.
##### requestUrl
类型:| `string`
---|---
原始请求网址.
##### timings
类型:| `Object`
---|---
该对象包含以下属性:
- `start`- 请求开始的时间.
- `socket`- 将套接字分配给请求的时间.
- `lookup`- DNS查找完成的时间.
- `connect`- 套接字成功连接的时间.
- `upload`- 请求完成上传的时间.
- `response`- 请求解雇的时间`response`事件.
- `end`- 响应解雇的时间`end`事件.
- `error`- 请求解雇的时间`error`事件.
- `phases` - `wait` - `timings.socket - timings.start` - `dns` - `timings.lookup - timings.socket` - `tcp` - `timings.connect - timings.lookup` - `request` - `timings.upload - timings.connect` - `firstByte` - `timings.response - timings.upload` - `download` - `timings.end - timings.response`-`total`-`timings.end - timings.start`要么`timings.error - timings.start`
**注意**:时间是`number`表示自UNIX纪元以来经过的毫秒数.
##### fromCache
类型:| `boolean`
---|---
是否从缓存中检索响应.
##### redirectUrls
类型:| `Array`
---|---
重定向网址.
##### retryCount
类型:| `number`
---|---
重试请求的次数.
#### Streams
**注意**:进度事件,重定向事件和请求/响应事件,也可以与promise一起使用.
#### got.stream(url, [options])
设`options.stream`为`true`.
返回带有其他活动的一个[双工流](https://nodejs.org/api/stream.html#stream_class_stream_duplex):
##### .on('request', request)
`request`事件获取请求的request对象.
**小费**: 您可以使用`request`事件,中止请求:
```js
got.stream('github.com')
.on('request', request => setTimeout(() => request.abort(), 50));
```
##### .on('response', response)
`response`事件获取最终请求的response对象.
##### .on('redirect', response, nextOptions)
`redirect`事件获取重定向的response对象。第二个参数是下一个重定向位置请求的选项.
##### .on('uploadProgress', progress)
##### .on('downloadProgress', progress)
上传(发送请求)和下载(接收响应)的进度事件。该`progress`参数是一个像这样的对象:
```js
{
percent: 0.1,
transferred: 1024,
total: 10240
}
```
如果无法检索大小(流式传输时,可能发生),`total`会是`null`.
```js
(async () => {
const response = await got('sindresorhus.com')
.on('downloadProgress', progress => {
// Report download progress
})
.on('uploadProgress', progress => {
// Report upload progress
});
console.log(response);
})();
```
##### .on('error', error, body, response)
`error`在协议错误的情况下,发出的事件(如`ENOTFOUND`等)或状态错误(4xx或5xx)。第二个参数是状态错误时服务器响应的主体。第三个参数是响应对象.
#### got.get(url, [options])
#### got.post(url, [options])
#### got.put(url, [options])
#### got.patch(url, [options])
#### got.head(url, [options])
#### got.delete(url, [options])
将`options.method`方法名称设置好,和做成请求.
### Instances
#### got.extend([options])
配置一个带默认`options`的新`got`实例。该`options`与父实例的`defaults.options`合并,合并是通过使用[`got.mergeOptions`](#gotmergeoptionsparentoptions-newoptions)。您可以使用在实例上的`.defaults`属性,访问已resolve的选项,.
```js
const client = got.extend({
baseUrl: 'https://example.com',
headers: {
'x-unicorn': 'rainbow'
}
});
client.get('/demo');
/* HTTP Request =>
* GET /demo HTTP/1.1
* Host: example.com
* x-unicorn: rainbow
*/
```
```js
(async () => {
const client = got.extend({
baseUrl: 'httpbin.org',
headers: {
'x-foo': 'bar'
}
});
const {headers} = (await client.get('/headers', {json: true})).body;
//=> headers['x-foo'] === 'bar'
const jsonClient = client.extend({
json: true,
headers: {
'x-baz': 'qux'
}
});
const {headers: headers2} = (await jsonClient.get('/headers')).body;
//=> headers2['x-foo'] === 'bar'
//=> headers2['x-baz'] === 'qux'
})();
```
*需要更多控制Got的行为? 看看[`got.create()`](advanced-creation.zh.md).*
#### got.mergeOptions(parentOptions, newOptions)
扩展父选项。避免使用[对象传播...](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals),因为它不能递归工作:
```js
const a = {headers: {cat: 'meow', wolf: ['bark', 'wrrr']}};
const b = {headers: {cow: 'moo', wolf: ['auuu']}};
{...a, ...b} // => {headers: {cow: 'moo', wolf: ['auuu']}}
got.mergeOptions(a, b) // => {headers: {cat: 'meow', cow: 'moo', wolf: ['auuu']}}
```
Options会深度合并到新对象。每个字段名的确定步骤如下:
> `a`为旧/父的,`b`为新的。
- 如果新属性设置为`undefined`,保留了旧的.
- 如果父属性是`URL`的实例,而新的值是`string`或者`URL`, 那就创建一个新的URL实例:[`new URL(new, parent)`](https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#Syntax).
- 如果新属性是普通`Object`:
- 如果父属性也是普通的`Object`, 那两个值递归合并为一个新的`Object`.
- 否则,只会深拷贝新值.
- 如果新属性是`Array`,它用新属性的深拷贝覆盖旧的.
- 否则,新值分配给对应的字段就好了。
#### got.defaults
类型:| `Object`
---|---
默认的Got选项.
## Errors
每个错误包含(如果可用)的属性字段 |
---|
`body`,|
`statusCode`,|
`statusMessage`,|
`host`,|
`hostname`|
`method`,|
`path`,|
`protocol`|
`url`|
使调试更容易.
在Promise模式下,
`response`也附加到错误.
#### got.CacheError
例如,当缓存方法失败时,如果数据库出现故障或存在文件系统错误.
#### got.RequestError
请求失败时,包含一个具有错误类代码的`code`属性,如`ECONNREFUSED`.
#### got.ReadError
从响应流中读取失败.
#### got.ParseError
当`json`选项已启用,服务器响应代码为2xx,和`JSON.parse`失败.
#### got.HTTPError
当服务器响应代码不是2xx时,包括`statusCode`,`statusMessage`,和`redirectUrls`属性.
#### got.MaxRedirectsError
当服务器重定向您十次以上时,包括一个`redirectUrls`属性,这是在放弃之前,重定向的一个URL数组.
#### got.UnsupportedProtocolError
不支持的协议时.
#### got.CancelError
请求被`.cancel()`中止时.
#### got.TimeoutError
当请求因一个[超时](#timeout)而中止时
## Aborting the request
Got返回的Promise有一个[`.cancel()`](https://github.com/sindresorhus/p-cancelable)。当调用时,会中止请求.
```js
(async () => {
const request = got(url, options);
// …
// In another part of the code
if (something) {
request.cancel();
}
// …
try {
await request;
} catch (error) {
if (request.isCanceled) { // Or `error instanceof got.CancelError`
// Handle cancelation
}
// Handle other errors
}
})();
```
## Cache
Got实现了[RFC 7234](http://httpwg.org/specs/rfc7234.html)兼容的HTTP缓存,可以在内存中开箱即用,并且可以使用各种存储适配器轻松插入。直接从缓存提供新缓存项,并使用`If-None-Match`/`If-Modified-Since`头重新验证过时的缓存项。您可以在[`cacheable-request`文件](https://github.com/lukechilds/cacheable-request)中,阅读有关基本缓存行为的更多信息.
您可以使用JavaScript`Map`类型,作为内存缓存:
```js
const got = require('got');
const map = new Map();
(async () => {
let response = await got('sindresorhus.com', {cache: map});
console.log(response.fromCache);
//=> false
response = await got('sindresorhus.com', {cache: map});
console.log(response.fromCache);
//=> true
})();
```
Got 内部使用[Keyv](https://github.com/lukechilds/keyv)支持各种存储适配器。对于更多伸缩性,你可以使用[官方Keyv存储适配器](https://github.com/lukechilds/keyv#official-storage-adapters):
```
$ npm install @keyv/redis
```
```js
const got = require('got');
const KeyvRedis = require('@keyv/redis');
const redis = new KeyvRedis('redis://user:pass@localhost:6379');
got('sindresorhus.com', {cache: redis});
```
Got提供了Map API内容的支持,因此可以轻松编写自己的存储适配器或使用第三方解决方案.
例如,以下所有,都是有效的存储适配器:
```js
const storageAdapter = new Map();
// Or
const storageAdapter = require('./my-storage-adapter');
// Or
const QuickLRU = require('quick-lru');
const storageAdapter = new QuickLRU({maxSize: 1000});
got('sindresorhus.com', {cache: storageAdapter});
```
查看[keyv文档](https://github.com/lukechilds/keyv)有关如何使用存储适配器的更多信息.
## Proxies
你可以使用[`tunnel`](https://github.com/koichik/node-tunnel)包,加上`agent`与代理一起工作:
```js
const got = require('got');
const tunnel = require('tunnel');
got('sindresorhus.com', {
agent: tunnel.httpOverHttp({
proxy: {
host: 'localhost'
}
})
});
```
查看下[`global-tunnel`](https://github.com/np-maintain/global-tunnel),如果您想为应用程序中的所有HTTP/HTTPS流量配置代理支持.
## Cookies
你可以使用[`tough-cookie`](https://github.com/salesforce/tough-cookie)包:
```js
const got = require('got');
const {CookieJar} = require('tough-cookie');
const cookieJar = new CookieJar();
cookieJar.setCookie('foo=bar', 'https://www.google.com');
got('google.com', {cookieJar});
```
## Form data
你可以使用[`form-data`](https://github.com/form-data/form-data),用表单数据创建POST请求:
```js
const fs = require('fs');
const got = require('got');
const FormData = require('form-data');
const form = new FormData();
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
got.post('google.com', {
body: form
});
```
## OAuth
你可以使用[`oauth-1.0a`](https://github.com/ddo/oauth-1.0a)包,创建签名的OAuth请求:
```js
const got = require('got');
const crypto = require('crypto');
const OAuth = require('oauth-1.0a');
const oauth = OAuth({
consumer: {
key: process.env.CONSUMER_KEY,
secret: process.env.CONSUMER_SECRET
},
signature_method: 'HMAC-SHA1',
hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
});
const token = {
key: process.env.ACCESS_TOKEN,
secret: process.env.ACCESS_TOKEN_SECRET
};
const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
got(url, {
headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
json: true
});
```
## Unix Domain Sockets
请求也可以通过[UNIX域名套接字](http://serverfault.com/questions/124517/whats-the-difference-between-unix-socket-and-tcp-ip-socket)发送出去。 使用以下URL方案:`PROTOCOL://unix:SOCKET:PATH`.
- `PROTOCOL` - `http`或`https` *(可选)*
- `SOCKET`- 一个UNIX域名套接字的绝对路径,例如:`/var/run/docker.sock`
- `PATH`- 请求路径,例如:`/v2/keys`
```js
got('http://unix:/var/run/docker.sock:/containers/json');
// Or without protocol (HTTP by default)
got('unix:/var/run/docker.sock:/containers/json');
```
## AWS
对AWS服务的请求,需要签署他们的标头(headers)。这可以通过使用[`aws4`](https://www.npmjs.com/package/aws4)包。这是一个用已签名的请求,查询["API网关"](https://docs.aws.amazon.com/apigateway/api-reference/signing-requests/)的示例..
```js
const AWS = require('aws-sdk');
const aws4 = require('aws4');
const got = require('got');
const chain = new AWS.CredentialProviderChain();
// Create a Got instance to use relative paths and signed requests
const awsClient = got.extend({
baseUrl: 'https://.execute-api..amazonaws.com//',
hooks: {
beforeRequest: [
async options => {
const credentials = await chain.resolvePromise();
aws4.sign(options, credentials);
}
]
}
});
const response = await awsClient('endpoint/path', {
// Request-specific options
});
```
## Testing
您可以通过使用[`nock`](https://github.com/node-nock/nock)包模拟端点:
```js
const got = require('got');
const nock = require('nock');
nock('https://sindresorhus.com')
.get('/')
.reply(200, 'Hello world!');
(async () => {
const response = await got('sindresorhus.com');
console.log(response.body);
//=> 'Hello world!'
})();
```
如果需要真正的集成测试,可以使用[`create-test-server`](https://github.com/lukechilds/create-test-server):
```js
const got = require('got');
const createTestServer = require('create-test-server');
(async () => {
const server = await createTestServer();
server.get('/', 'Hello world!');
const response = await got(server.url);
console.log(response.body);
//=> 'Hello world!'
await server.close();
})();
```
## Tips
### User Agent
设置`'user-agent'`头是个好主意,因此提供者可以更容易地看到它们的资源是如何使用的。默认情况下,它是指向这个存储库的URL。当然您也可以设置为`null`禁用.
```js
const got = require('got');
const pkg = require('./package.json');
got('sindresorhus.com', {
headers: {
'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
}
});
got('sindresorhus.com', {
headers: {
'user-agent': null
}
});
```
### 304 Responses
记住,如果你发送一个`if-modified-since`标题。和接收到了`304 Not Modified`响应,主体-body就会是空的。缓存和检索主体内容是您的职责.
### Custom endpoints
使用`got.extend()`让它更好地与REST API一起工作。特别是你使用了`baseUrl`选项.
**注:**不要对[`got.create()`](advanced-creation.zh.md)感到疑惑,它没有默认值.
```js
const got = require('got');
const pkg = require('./package.json');
const custom = got.extend({
baseUrl: 'example.com',
json: true,
headers: {
'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
}
});
// Use `custom` exactly how you use `got`
(async () => {
const list = await custom('/v1/users/list');
})();
```
*需要将一些实例合并为单个实例吗? 查看[`got.mergeInstances()`](advanced-creation.zh.md#merging-instances).*
### Experimental HTTP2 support
GET提供了[`http2-wrapper`](https://github.com/szmarczak/http2-wrapper)包,使用HTTP2的实验支持:
```js
const got = require('got');
const {request} = require('http2-wrapper');
const h2got = got.extend({request});
(async () => {
const {body} = await h2got('https://nghttp2.org/httpbin/headers');
console.log(body);
})();
```
## Comparison
| | `got` | `request` | `node-fetch` | `axios` |
|-----------------------|:------------:|:------------:|:------------:|:------------:|
| HTTP/2 支持 | ❔ | ✖ | ✖ | ✖ |
| Browser 支持 | ✖ | ✖ | ✔* | ✔ |
| Electron 支持 | ✔ | ✖ | ✖ | ✖ |
| Promise API | ✔ | ✔ | ✔ | ✔ |
| Stream API | ✔ | ✔ | Node.js only | ✖ |
| Request 中止 | ✔ | ✖ | ✖ | ✔ |
| RFC compliant caching | ✔ | ✖ | ✖ | ✖ |
| Cookies (out-of-box) | ✔ | ✔ | ✖ | ✖ |
| 跟踪 重定向网址 | ✔ | ✔ | ✔ | ✔ |
| 失败重试 | ✔ | ✖ | ✖ | ✖ |
| Progress 事件 | ✔ | ✖ | ✖ | Browser only |
| 可控 gzip/deflate | ✔ | ✔ | ✔ | ✔ |
| timeouts 优化 | ✔ | ✖ | ✖ | ✖ |
| Timings | ✔ | ✔ | ✖ | ✖ |
| Errors 元数据 | ✔ | ✖ | ✖ | ✔ |
| JSON 模式 | ✔ | ✔ | ✖ | ✔ |
| Custom defaults | ✔ | ✔ | ✖ | ✔ |
| Composable | ✔ | ✖ | ✖ | ✖ |
| Hooks | ✔ | ✖ | ✖ | ✔ |
| Issues open | ![][gio] | ![][rio] | ![][nio] | ![][aio] |
| Issues closed | ![][gic] | ![][ric] | ![][nic] | ![][aic] |
| Downloads | ![][gd] | ![][rd] | ![][nd] | ![][ad] |
| Coverage | ![][gc] | ![][rc] | ![][nc] | ![][ac] |
| Build | ![][gb] | ![][rb] | ![][nb] | ![][ab] |
| Bugs | ![][gbg] | ![][rbg] | ![][nbg] | ![][abg] |
| Dependents | ![][gdp] | ![][rdp] | ![][ndp] | ![][adp] |
| Install size | ![][gis] | ![][ris] | ![][nis] | ![][ais] |
\*它几乎与浏览器`fetch` API兼容.
❔ 实验支持.
[gio]: https://img.shields.io/github/issues/sindresorhus/got.svg
[rio]: https://img.shields.io/github/issues/request/request.svg
[nio]: https://img.shields.io/github/issues/bitinn/node-fetch.svg
[aio]: https://img.shields.io/github/issues/axios/axios.svg
[gic]: https://img.shields.io/github/issues-closed/sindresorhus/got.svg
[ric]: https://img.shields.io/github/issues-closed/request/request.svg
[nic]: https://img.shields.io/github/issues-closed/bitinn/node-fetch.svg
[aic]: https://img.shields.io/github/issues-closed/axios/axios.svg
[gd]: https://img.shields.io/npm/dm/got.svg
[rd]: https://img.shields.io/npm/dm/request.svg
[nd]: https://img.shields.io/npm/dm/node-fetch.svg
[ad]: https://img.shields.io/npm/dm/axios.svg
[gc]: https://coveralls.io/repos/github/sindresorhus/got/badge.svg?branch=master
[rc]: https://coveralls.io/repos/github/request/request/badge.svg?branch=master
[nc]: https://coveralls.io/repos/github/bitinn/node-fetch/badge.svg?branch=master
[ac]: https://coveralls.io/repos/github/mzabriskie/axios/badge.svg?branch=master
[gb]: https://travis-ci.org/sindresorhus/got.svg?branch=master
[rb]: https://travis-ci.org/request/request.svg?branch=master
[nb]: https://travis-ci.org/bitinn/node-fetch.svg?branch=master
[ab]: https://travis-ci.org/axios/axios.svg?branch=master
[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open
[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open
[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open
[abg]: https://badgen.net/github/label-issues/axios/axios/bug/open
[gdp]: https://badgen.net/npm/dependents/got
[rdp]: https://badgen.net/npm/dependents/request
[ndp]: https://badgen.net/npm/dependents/node-fetch
[adp]: https://badgen.net/npm/dependents/axios
[gis]: https://packagephobia.now.sh/badge?p=got
[ris]: https://packagephobia.now.sh/badge?p=request
[nis]: https://packagephobia.now.sh/badge?p=node-fetch
[ais]: https://packagephobia.now.sh/badge?p=axios
## Related
- [gh-got](https://github.com/sindresorhus/gh-got) - Got 便利包,与GitHub API交互
- [gl-got](https://github.com/singapore/gl-got) - Got 便利包,与Gitlab API交互
- [travis-got](https://github.com/samverschueren/travis-got) - Got 便利包,与Travis API交互
- [graphql-got](https://github.com/kevva/graphql-got) - Got 便利包,与GraphQL API交互
- [GotQL](https://github.com/khaosdoctor/gotql) - Got 便利包,与GraphQL API交互, 但是使用JSON解析替代字符串
## Maintainers
| [](https://sindresorhus.com) | [](https://github.com/floatdrop) | [](https://github.com/AlexTes) | [](https://github.com/lukechilds) | [](https://github.com/szmarczak) | [](https://github.com/brandon93s) |
| ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [Sindre Sorhus](https://sindresorhus.com) | [Vsevolod Strukchinsky](https://github.com/floatdrop) | [Alexander Tesfamichael](https://alextes.me) | [Luke Childs](https://github.com/lukechilds) | [Szymon Marczak](https://github.com/szmarczak) | [Brandon Smith](https://github.com/brandon93s) |
## License
MIT