Home

Awesome

sindresorhus/got explain translate-svg

<!-- [![size-img]][size] -->

「 简化的HTTP请求 」

中文 | english


校对 ✅

<!-- doc-templite START generated --> <!-- repo = 'sindresorhus/got' --> <!-- commit = '7f18ef397341214d9f46d774f69e65d6cdd95494' --> <!-- time = '2018-11-08' -->
翻译的原文与日期最新更新更多
commit⏰ 2018-11-08last中文翻译
<!-- doc-templite END generated -->

贡献

欢迎 👏 勘误/校对/更新贡献 😊 具体贡献请看

生活

If help, buy me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰


<div align="center"> <br> <br> <img width="360" src="https://github.com/sindresorhus/got/blob/master/media/logo.svg" alt="Got"> <br> <br> <br> <p align="center">非常感谢 <a href="https://moxy.studio"><img src="https://sindresorhus.com/assets/thanks/moxy-logo.svg" width="150"></a> 赞助 me! </p> <br> <br> </div>

简化的HTTP请求

Build Status: Linux Coverage Status Downloads Install size

Got是一个人性化,且功能强大的HTTP请求库.

它的创建是因为常用的request包过臃肿: Install size

Got是Node.js的请求库。对于浏览器的请求,我们建议ky.

Highlights

了解Got,如何与其他HTTP库进行比较

Install

$ npm install got
<a href="https://www.patreon.com/sindresorhus"> <img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160"> </a>

Usage

const got = require('got');

(async () => {
	try {
		const response = await got('sindresorhus.com');
		console.log(response.body);
		//=> '<!doctype html> ...'
	} catch (error) {
		console.log(error.response.body);
		//=> 'Internal server error ...'
	}
})();
Streams
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])

参数
url
options
url
类型:string Object
options
类型:Object

参数 |> Streams / baseUrl / headers / stream / body / cookieJar / encoding / form / json / query / timeout / retry / followRedirect / decompress / cache / request / useElectronNet / throwHttpErrors / agent / hooks

任何一个https.request的选项.

baseUrl
类型:string Object

使用got.extend()时非常有用,用于创建利基特定的Got实例.

可以是字符串或WHATWG URL.

削减baseUrl的结尾,拼接开始的url参数,且是可选的:

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
默认:{}

请求标头.

stream
类型:boolean
默认:false

返回一个Stream,而不是Promise。这相当于调用got.stream(url, [options]).

body
类型:string Buffer stream.Readable form-data实例

如果您提供此选项,got.stream()将是只读的.

POST请求发送的主体.

如果存在optionsoptions.method未设定,options.method将被设置为POST.

content-length标题将自动设置,如果body是一个string/Buffer/fs.createReadStream实例/form-data实例,和content-lengthtransfer-encoding就不再是options.headers的手动设置.

cookieJar
类型:tough.CookieJar实例

Cookie支持.您不必关心解析或如何存储它们.例子.

注意: options.headers.cookie将被覆盖.

encoding
类型:string null
默认:'utf8'

编码-Encoding用于响应数据的setEncoding。如果null, 响应body会返回一个Buffer(二进制数据).

form
类型:boolean
默认:false

如果您提供此选项,got.stream()将是只读的.

如果设置为trueContent-Type标头未设置,它将被设置为application/x-www-form-urlencoded.

body必须是一个普通的对象。它将使用(new URLSearchParams(object)).toString()转换为查询字符串.

json
类型:boolean
默认:false

如果你使用got.stream(),此选项将被忽略.

如果设置为trueContent-Type标头未设置,它将被设置为application/json.

JSON.parse解析响应主体,并设置accept标题为application/json。如果与form选项一起使用,body将字符串化为查询字符串,并将响应解析为JSON.

body必须是普通对象或数组,和能对其进行字符串化.

query
类型:string Object<string, string|number> URLSearchParams

添加到请求URL的查询字符串。这将覆盖url的查询字符串.

如果你需要传入一个数组,你可以使用一个URLSearchParams,例如:

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包:

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错误(a.k.a.request属性)之前,等待服务器结束响应的毫秒数。默认情况下,没有超时.

这也会接受object,使用以下字段来约束请求生命周期的每个阶段的持续时间:

retry
类型:number Object<br>
默认:重试:2
方法:GET PUT HEAD DELETE OPTIONS TRACE
statusCodes:408 413 429 500 502 503 504
maxRetryAfter:undefined

如果maxRetryAfter被设置为undefined,它会用options.timeout.<br>如果Retry-After标头大于maxRetryAfter,它将取消请求.

重试之间的延迟计算是1000 * Math.pow(2, retry) + Math.random() * 100函数,这里的retry是尝试数(从1开始).

retries属性可以

**注意:**它仅在指定的方法,状态代码和这些网络错误上重试:

followRedirect
类型:boolean
默认:true

定义是否应自动遵循重定向响应.

请注意,如果服务器发送回来一个303,以响应任何请求类型(POST,DELETE等等),Got会自动通过GET请求,位置头中指向的资源。这符合规范.

decompress
类型:boolean
默认:true

自动解压响应。这将设置accept-encoding标题为gzip, deflate,除非你自己设定.

如果禁用此选项,则会将压缩响应作为一个Buffer返回。如果您想自己处理解压或stream式处理原始压缩数据, 这可能很有用.

cache
类型:Object
默认:false

缓存适配器实例用于存储缓存的数据.

request
类型:Function<br>
默认:http.request https.request (取决于协议)

自定义请求函数.这样做的主要目的是为了通过包装HTTP2,以此支持这个协议.

useElectronNet
类型:boolean
默认:false

在Electron中使用时,Got会使用electron.net替代Node.jshttp模块。根据Electron的文档,它应该是完全兼容的,但其实不是完全兼容.看到#443#461.

throwHttpErrors
类型:boolean
默认:true

确定是否抛出got.HTTPError错误响应(非2xx状态代码).

如果禁用此选项,在请求遇到错误状态代码,会使用response resolve,而不是抛出got.HTTPError。如果您正在检查资源可用性,并且期望出现错误响应,这可能很有用.

agent

对应http.requestagent选项,但有一个额外的功能:

如果您需要针对不同协议的不同代理,则可以将代理映射传递给agent选项。这是必要的,因为对一个协议的请求可能会重定向到另一个协议。在这种情况下,Got将为您切换到正确的协议代理.

const got = require('got');
const HttpAgent = require('agentkeepalive');
const {HttpsAgent} = HttpAgent;

got('sindresorhus.com', {
	agent: {
		http: new HttpAgent(),
		https: new HttpsAgent()
	}
});
hooks
类型:Object<string, Function[]>

钩子允许在请求生命周期中进行修改。钩子函数可以是异步的,和也能串行运行的.

hooks.beforeRequest
类型:Function[]
默认:[]

调用标准的 请求选项。在发送请求之前,不会对请求进行进一步更改。这对结合got.extend()got.create()使用,特别有用,当您想要创建一个API客户端时,例如,使用HMAC签名.

AWS部分举的例子.

注意:如果你修改了body,你也需要修改content-length标题,因为它已经被计算和分配.

hooks.beforeRedirect
类型:Function[]
默认:[]

调用标准的 请求选项。Got的请求不会进一步更改.当您想要避免死站点时,这尤其有用.例:

const got = require('got');

got('example.com', {
	hooks: {
		beforeRedirect: [
			options => {
				if (options.hostname === 'deadSite') {
					options.hostname = 'fallbackSite';
				}
			}
		]
	}
});
hooks.beforeRetry
类型:Function[]
默认:[]

调用标准的 请求选项,错误和重试计数。Got的请求不会进一步更改。在下次尝试之前,需要一些额外的工作时,这尤其有用.例:

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[]
默认:[]

调用响应对象和重试函数.

每个函数都应该返回响应。当您想要刷新访问令牌时,这尤其有用.例:

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响应流但是,如果从缓存返回,那它会是一个类似响应的对象和行为方式相同.

参数 |> body / url / requestUrl / timings / fromCache / redirectUrls / retryCount /

body
类型:string Object (取决于options.json)

请求的结果.

url
类型:string

重定向后的请求URL或最终URL.

requestUrl
类型:string

原始请求网址.

timings
类型:Object

该对象包含以下属性:

注意:时间是number表示自UNIX纪元以来经过的毫秒数.

fromCache
类型:boolean

是否从缓存中检索响应.

redirectUrls
类型:Array

重定向网址.

retryCount
类型:number

重试请求的次数.

Streams

注意:进度事件,重定向事件和请求/响应事件,也可以与promise一起使用.

got.stream(url, [options])

options.streamtrue.

返回带有其他活动的一个双工流:

.on('request', request)

request事件获取请求的request对象.

小费: 您可以使用request事件,中止请求:

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参数是一个像这样的对象:

{
	percent: 0.1,
	transferred: 1024,
	total: 10240
}

如果无法检索大小(流式传输时,可能发生),total会是null.

(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。您可以使用在实例上的.defaults属性,访问已resolve的选项,.

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
 */
(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().

got.mergeOptions(parentOptions, newOptions)

扩展父选项。避免使用对象传播...,因为它不能递归工作:

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']}}
<!-- HERE -->

Options会深度合并到新对象。每个字段名的确定步骤如下:

a为旧/父的,b为新的。

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

当请求因一个超时而中止时

Aborting the request

Got返回的Promise有一个.cancel()。当调用时,会中止请求.

(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
	}
})();

<a name="cache-adapters"></a>

Cache

Got实现了RFC 7234兼容的HTTP缓存,可以在内存中开箱即用,并且可以使用各种存储适配器轻松插入。直接从缓存提供新缓存项,并使用If-None-Match/If-Modified-Since头重新验证过时的缓存项。您可以在cacheable-request文件中,阅读有关基本缓存行为的更多信息.

您可以使用JavaScriptMap类型,作为内存缓存:

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支持各种存储适配器。对于更多伸缩性,你可以使用官方Keyv存储适配器:

$ npm install @keyv/redis
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内容的支持,因此可以轻松编写自己的存储适配器或使用第三方解决方案.

例如,以下所有,都是有效的存储适配器:

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文档有关如何使用存储适配器的更多信息.

Proxies

你可以使用tunnel包,加上agent与代理一起工作:

const got = require('got');
const tunnel = require('tunnel');

got('sindresorhus.com', {
	agent: tunnel.httpOverHttp({
		proxy: {
			host: 'localhost'
		}
	})
});

查看下global-tunnel,如果您想为应用程序中的所有HTTP/HTTPS流量配置代理支持.

Cookies

你可以使用tough-cookie包:

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,用表单数据创建POST请求:

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包,创建签名的OAuth请求:

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域名套接字发送出去。 使用以下URL方案:PROTOCOL://unix:SOCKET:PATH.

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包。这是一个用已签名的请求,查询"API网关"的示例..

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://<api-id>.execute-api.<api-region>.amazonaws.com/<stage>/',
	hooks: {
		beforeRequest: [
			async options => {
				const credentials = await chain.resolvePromise();
				aws4.sign(options, credentials);
			}
		]
	}
});

const response = await awsClient('endpoint/path', {
	// Request-specific options
});

Testing

您可以通过使用nock包模拟端点:

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:

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禁用.

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()感到疑惑,它没有默认值.

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().

Experimental HTTP2 support

GET提供了http2-wrapper包,使用HTTP2的实验支持:

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

gotrequestnode-fetchaxios
HTTP/2 支持
Browser 支持✔*
Electron 支持
Promise API
Stream APINode.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
Issues closed
Downloads
Coverage
Build
Bugs
Dependents
Install size

*它几乎与浏览器fetch API兼容.<br> ❔ 实验支持.

<!-- ISSUES OPEN --> <!-- ISSUES CLOSED --> <!-- DOWNLOADS --> <!-- COVERAGE --> <!-- BUILD --> <!-- BUGS --> <!-- DEPENDENTS --> <!-- INSTALL SIZE -->

Related

Maintainers

Sindre SorhusVsevolod StrukchinskyAlexander TesfamichaelLuke ChildsSzymon MarczakBrandon Smith
Sindre SorhusVsevolod StrukchinskyAlexander TesfamichaelLuke ChildsSzymon MarczakBrandon Smith

License

MIT