|
66 | 66 | - [HTML Form Posting](#-html-form-posting-browser) |
67 | 67 | - [🆕 Progress capturing](#-progress-capturing) |
68 | 68 | - [🆕 Rate limiting](#-progress-capturing) |
| 69 | + - [🆕 AxiosHeaders](#-axiosheaders) |
69 | 70 | - [Semver](#semver) |
70 | 71 | - [Promises](#promises) |
71 | 72 | - [TypeScript](#typescript) |
@@ -1291,6 +1292,260 @@ const {data} = await axios.post(LOCAL_SERVER_URL, myBuffer, { |
1291 | 1292 | }); |
1292 | 1293 | ``` |
1293 | 1294 |
|
| 1295 | +## 🆕 AxiosHeaders |
| 1296 | +
|
| 1297 | +Axios has its own `AxiosHeaders` class to manipulate headers using a Map-like API that guarantees caseless work. |
| 1298 | +Although HTTP is case-insensitive in headers, Axios will retain the case of the original header for stylistic reasons |
| 1299 | +and for a workaround when servers mistakenly consider the header's case. |
| 1300 | +The old approach of directly manipulating headers object is still available, but deprecated and not recommended for future usage. |
| 1301 | +
|
| 1302 | +### Working with headers |
| 1303 | +
|
| 1304 | +An AxiosHeaders object instance can contain different types of internal values. that control setting and merging logic. |
| 1305 | +The final headers object with string values is obtained by Axios by calling the `toJSON` method. |
| 1306 | +
|
| 1307 | +> Note: By JSON here we mean an object consisting only of string values intended to be sent over the network. |
| 1308 | +
|
| 1309 | +The header value can be one of the following types: |
| 1310 | +- `string` - normal string value that will be sent to the server |
| 1311 | +- `null` - skip header when rendering to JSON |
| 1312 | +- `false` - skip header when rendering to JSON, additionally indicates that `set` method must be called with `rewrite` option set to `true` |
| 1313 | + to overwrite this value (Axios uses this internally to allow users to opt out of installing certain headers like `User-Agent` or `Content-Type`) |
| 1314 | +- `undefined` - value is not set |
| 1315 | +
|
| 1316 | +> Note: The header value is considered set if it is not equal to undefined. |
| 1317 | +
|
| 1318 | +The headers object is always initialized inside interceptors and transformers: |
| 1319 | +
|
| 1320 | +```ts |
| 1321 | + axios.interceptors.request.use((request: InternalAxiosRequestConfig) => { |
| 1322 | + request.headers.set('My-header', 'value'); |
| 1323 | + |
| 1324 | + request.headers.set({ |
| 1325 | + "My-set-header1": "my-set-value1", |
| 1326 | + "My-set-header2": "my-set-value2" |
| 1327 | + }); |
| 1328 | + |
| 1329 | + request.headers.set('User-Agent', false); // disable subsequent setting the header by Axios |
| 1330 | + |
| 1331 | + request.headers.setContentType('text/plain'); |
| 1332 | + |
| 1333 | + request.headers['My-set-header2'] = 'newValue' // direct access is deprecated |
| 1334 | + |
| 1335 | + return request; |
| 1336 | + } |
| 1337 | + ); |
| 1338 | +```` |
| 1339 | + |
| 1340 | +You can iterate over an `AxiosHeaders` instance using a `for...of` statement: |
| 1341 | + |
| 1342 | +````js |
| 1343 | +const headers = new AxiosHeaders({ |
| 1344 | + foo: '1', |
| 1345 | + bar: '2', |
| 1346 | + baz: '3' |
| 1347 | +}); |
| 1348 | + |
| 1349 | +for(const [header, value] of headers) { |
| 1350 | + console.log(header, value); |
| 1351 | +} |
| 1352 | + |
| 1353 | +// foo 1 |
| 1354 | +// bar 2 |
| 1355 | +// baz 3 |
| 1356 | +```` |
| 1357 | + |
| 1358 | +### new AxiosHeaders(headers?) |
| 1359 | + |
| 1360 | +Constructs a new `AxiosHeaders` instance. |
| 1361 | + |
| 1362 | +``` |
| 1363 | +constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); |
| 1364 | +``` |
| 1365 | + |
| 1366 | +If the headers object is a string, it will be parsed as RAW HTTP headers. |
| 1367 | + |
| 1368 | +````js |
| 1369 | +const headers = new AxiosHeaders(` |
| 1370 | +Host: www.bing.com |
| 1371 | +User-Agent: curl/7.54.0 |
| 1372 | +Accept: */*`); |
| 1373 | + |
| 1374 | +console.log(headers); |
| 1375 | + |
| 1376 | +// Object [AxiosHeaders] { |
| 1377 | +// host: 'www.bing.com', |
| 1378 | +// 'user-agent': 'curl/7.54.0', |
| 1379 | +// accept: '*/*' |
| 1380 | +// } |
| 1381 | +```` |
| 1382 | + |
| 1383 | +### AxiosHeaders#set |
| 1384 | + |
| 1385 | +```ts |
| 1386 | +set(headerName, value: Axios, rewrite?: boolean); |
| 1387 | +set(headerName, value, rewrite?: (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean); |
| 1388 | +set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean); |
| 1389 | +``` |
| 1390 | + |
| 1391 | +The `rewrite` argument controls the overwriting behavior: |
| 1392 | +- `false` - do not overwrite if header's value is set (is not `undefined`) |
| 1393 | +- `undefined` (default) - overwrite the header unless its value is set to `false` |
| 1394 | +- `true` - rewrite anyway |
| 1395 | +
|
| 1396 | +The option can also accept a user-defined function that determines whether the value should be overwritten or not. |
| 1397 | +
|
| 1398 | +Returns `this`. |
| 1399 | +
|
| 1400 | +### AxiosHeaders#get(header) |
| 1401 | +
|
| 1402 | +``` |
| 1403 | + get(headerName: string, matcher?: true | AxiosHeaderMatcher): AxiosHeaderValue; |
| 1404 | + get(headerName: string, parser: RegExp): RegExpExecArray | null; |
| 1405 | +```` |
| 1406 | +
|
| 1407 | +Returns the internal value of the header. It can take an extra argument to parse the header's value with `RegExp.exec`, |
| 1408 | +matcher function or internal key-value parser. |
| 1409 | + |
| 1410 | +```ts |
| 1411 | +const headers = new AxiosHeaders({ |
| 1412 | + 'Content-Type': 'multipart/form-data; boundary=Asrf456BGe4h' |
| 1413 | +}); |
| 1414 | + |
| 1415 | +console.log(headers.get('Content-Type')); |
| 1416 | +// multipart/form-data; boundary=Asrf456BGe4h |
| 1417 | + |
| 1418 | +console.log(headers.get('Content-Type', true)); // parse key-value pairs from a string separated with \s,;= delimiters: |
| 1419 | +// [Object: null prototype] { |
| 1420 | +// 'multipart/form-data': undefined, |
| 1421 | +// boundary: 'Asrf456BGe4h' |
| 1422 | +// } |
| 1423 | + |
| 1424 | + |
| 1425 | +console.log(headers.get('Content-Type', (value, name, headers) => { |
| 1426 | + return String(value).replace(/a/g, 'ZZZ'); |
| 1427 | +})); |
| 1428 | +// multipZZZrt/form-dZZZtZZZ; boundZZZry=Asrf456BGe4h |
| 1429 | + |
| 1430 | +console.log(headers.get('Content-Type', /boundary=(\w+)/)?.[0]); |
| 1431 | +// boundary=Asrf456BGe4h |
| 1432 | + |
| 1433 | +``` |
| 1434 | +
|
| 1435 | +Returns the value of the header. |
| 1436 | +
|
| 1437 | +### AxiosHeaders#has(header, matcher?) |
| 1438 | +
|
| 1439 | +``` |
| 1440 | +has(header: string, matcher?: AxiosHeaderMatcher): boolean; |
| 1441 | +``` |
| 1442 | +
|
| 1443 | +Returns `true` if the header is set (has no `undefined` value). |
| 1444 | +
|
| 1445 | +### AxiosHeaders#delete(header, matcher?) |
| 1446 | +
|
| 1447 | +``` |
| 1448 | +delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; |
| 1449 | +``` |
| 1450 | +
|
| 1451 | +Returns `true` if at least one header has been removed. |
| 1452 | +
|
| 1453 | +### AxiosHeaders#clear(matcher?) |
| 1454 | +
|
| 1455 | +``` |
| 1456 | +clear(matcher?: AxiosHeaderMatcher): boolean; |
| 1457 | +``` |
| 1458 | +
|
| 1459 | +Removes all headers. |
| 1460 | +Unlike the `delete` method matcher, this optional matcher will be used to match against the header name rather than the value. |
| 1461 | +
|
| 1462 | +```ts |
| 1463 | +const headers = new AxiosHeaders({ |
| 1464 | + 'foo': '1', |
| 1465 | + 'x-foo': '2', |
| 1466 | + 'x-bar': '3', |
| 1467 | +}); |
| 1468 | + |
| 1469 | +console.log(headers.clear(/^x-/)); // true |
| 1470 | + |
| 1471 | +console.log(headers.toJSON()); // [Object: null prototype] { foo: '1' } |
| 1472 | +``` |
| 1473 | +
|
| 1474 | +Returns `true` if at least one header has been cleared. |
| 1475 | +
|
| 1476 | +### AxiosHeaders#normalize(format); |
| 1477 | +
|
| 1478 | +If the headers object was changed directly, it can have duplicates with the same name but in different cases. |
| 1479 | +This method normalizes the headers object by combining duplicate keys into one. |
| 1480 | +Axios uses this method internally after calling each interceptor. |
| 1481 | +Set `format` to true for converting headers name to lowercase and capitalize the initial letters (`cOntEnt-type` => `Content-Type`) |
| 1482 | +
|
| 1483 | +```js |
| 1484 | +const headers = new AxiosHeaders({ |
| 1485 | + 'foo': '1', |
| 1486 | +}); |
| 1487 | + |
| 1488 | +headers.Foo = '2'; |
| 1489 | +headers.FOO = '3'; |
| 1490 | + |
| 1491 | +console.log(headers.toJSON()); // [Object: null prototype] { foo: '1', Foo: '2', FOO: '3' } |
| 1492 | +console.log(headers.normalize().toJSON()); // [Object: null prototype] { foo: '3' } |
| 1493 | +console.log(headers.normalize(true).toJSON()); // [Object: null prototype] { Foo: '3' } |
| 1494 | +``` |
| 1495 | +
|
| 1496 | +Returns `this`. |
| 1497 | +
|
| 1498 | +### AxiosHeaders#concat(...targets) |
| 1499 | +
|
| 1500 | +``` |
| 1501 | +concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>): AxiosHeaders; |
| 1502 | +``` |
| 1503 | +
|
| 1504 | +Merges the instance with targets into a new `AxiosHeaders` instance. If the target is a string, it will be parsed as RAW HTTP headers. |
| 1505 | +
|
| 1506 | +Returns a new `AxiosHeaders` instance. |
| 1507 | +
|
| 1508 | +### AxiosHeaders#toJSON(asStrings?) |
| 1509 | +
|
| 1510 | +```` |
| 1511 | +toJSON(asStrings?: boolean): RawAxiosHeaders; |
| 1512 | +```` |
| 1513 | +
|
| 1514 | +Resolve all internal headers values into a new null prototype object. |
| 1515 | +Set `asStrings` to true to resolve arrays as a string containing all elements, separated by commas. |
| 1516 | +
|
| 1517 | +### AxiosHeaders.from(thing?) |
| 1518 | +
|
| 1519 | +```` |
| 1520 | +from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; |
| 1521 | +```` |
| 1522 | +
|
| 1523 | +Returns a new `AxiosHeaders` instance created from the raw headers passed in, |
| 1524 | +or simply returns the given headers object if it's an `AxiosHeaders` instance. |
| 1525 | +
|
| 1526 | +### AxiosHeaders.concat(...targets) |
| 1527 | +
|
| 1528 | +```` |
| 1529 | +concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>): AxiosHeaders; |
| 1530 | +```` |
| 1531 | +
|
| 1532 | +Returns a new `AxiosHeaders` instance created by merging the target objects. |
| 1533 | +
|
| 1534 | +### Shortcuts |
| 1535 | +
|
| 1536 | +The following shortcuts are available: |
| 1537 | +
|
| 1538 | +- `setContentType`, `getContentType`, `hasContentType` |
| 1539 | +
|
| 1540 | +- `setContentLength`, `getContentLength`, `hasContentLength` |
| 1541 | +
|
| 1542 | +- `setAccept`, `getAccept`, `hasAccept` |
| 1543 | +
|
| 1544 | +- `setUserAgent`, `getUserAgent`, `hasUserAgent` |
| 1545 | +
|
| 1546 | +- `setContentEncoding`, `getContentEncoding`, `hasContentEncoding` |
| 1547 | +
|
| 1548 | +
|
1294 | 1549 | ## Semver |
1295 | 1550 |
|
1296 | 1551 | Until axios reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.5.1`, and `0.5.4` will have the same API, but `0.6.0` will have breaking changes. |
|
0 commit comments