Skip to content

Commit 77291c0

Browse files
authored
[Explainer] Add an alternative queueBeacon() (WICG#69)
Address comments from WICG#68 Also a follow up to WICG#50 and WebKit/standards-positions#85 (comment)
1 parent 0af026c commit 77291c0

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ and it would not be possible to restrict what that callback does
363363
It also doesn’t allow for other niceties such as resilience against crashes or batching of beacons,
364364
and complicates the already sufficiently complicated page lifecycle.
365365

366-
### Extending `fetch` API
366+
### Extending `fetch()` API
367367

368368
> **NOTE:** Discussions in [#52] and [#50].
369369
@@ -388,6 +388,8 @@ fetch('/send_beacon', {deferSend: true});
388388
// Promise may not resolve and response may be dropped.
389389
```
390390

391+
#### Problem
392+
391393
However, there are several problem with this approach:
392394

393395
1. **The Fetch API shape is not designed for this (1) purpose.** Fundamentally, `window.fetch` returns a Promise with Response to resolve, which don't make sense for beaconing at page discard that doesn't expect to process response.
@@ -396,7 +398,7 @@ However, there are several problem with this approach:
396398

397399
The above problems suggest that a new API is neccessary for our purpose.
398400

399-
### Extending `sendBeacon` API
401+
### Extending `navigator.sendBeacon()` API
400402

401403
> **NOTE:** Discussions in [WebKit's standard position](https://github.com/WebKit/standards-positions/issues/85#issuecomment-1418381239).
402404
@@ -407,10 +409,10 @@ navigator.sendBeacon(url): bool
407409
navigator.sendBeacon(url, data): bool
408410
```
409411

410-
To support the [requirements](#requirements) and to make the new API backward compatible, we propose the following shape:
412+
To meet the [requirements](#requirements) and to make the new API backward compatible, we propose the following shape:
411413

412414
```ts
413-
navigator.sendBeacon(url, fetchOptions): PendingBeacon
415+
navigator.sendBeacon(url, data, fetchOptions): PendingBeacon
414416
```
415417

416418
An optional dictionary argument `fetchOptions` can be passed in, which changes the return value from `bool` to `PendingBeacon` proposed in the above [PendingBeacon](#pendingbeacon) section. Some details to note:
@@ -419,25 +421,36 @@ An optional dictionary argument `fetchOptions` can be passed in, which changes t
419421
2. `fetchOptions` can only be a subset of the [Fetch API]'s [`RequestInit`] object:
420422
1. `method`: one of `GET` or `POST`.
421423
2. `headers`: supports custom headers, which unblocks [#50].
422-
3. `body`: `TypedArray`, `DataView` are not supported in the old API.
424+
3. `body`: **not supported**. POST body should be in `data` argument.
423425
4. `credentials`: enforcing `same-origin` to be consistent.
424426
5. `cache`: not supported.
425427
6. `redirect`: enforcing `follow`.
426428
7. `referrer`: enforcing same-origin URL.
427429
8. `referrerPolicy`: enforcing `same-origin`.
428430
9. `keepalive`: enforcing `true`.
429431
10. `integrity`: not supported.
430-
11. `signal`: not supported. See below
432+
11. `signal`: **not supported**.
433+
* The reason why `signal` and `AbortController` are not desired is that we needs more than just aborting the requests. It is essential to check a beacon's pending states and to update or accumulate data. Supporting these requirements via the returned `PendingBeacon` object allows more flexibility.
431434
12. `priority`: enforcing `auto`.
435+
3. `data`: For `GET` beacon, it must be `null` or `undefined`.
436+
4. The return value must supports updating request URL or data, hence `PendingBeacon` object.
437+
438+
#### Problem
432439

433-
The reason why `signal` and `AbortController` is not desired is that the proposal would like to supports more than just aborting the requests, it also needs to check pending states and accumulate data. Supporting these requirements via the returned `PendingBeacon` object allows more flexibility.
440+
* The above API itself is enough for the requirements (2) and (3), but cannot achieve the requirement (1), delaying the request.
441+
* The function name `sendBeacon` semantic doesn't make sense for the "delaying" behavior.
442+
* Combing the subset of `fetchOptions` along with the existing `data` parameter are error-proning.
434443

435-
The above API itself is enough for the requirements (2) and (3), but not for (1), which requires delaying the request. As the `sendBeacon` semantic doesn't make sense for the "delaying" behavior, proposing a new function is better:
444+
### Introducing `navigator.queueBeacon()` API
445+
446+
To imprvoe from "Extending `navigator.sendBeacon()` API, it's better with a new function:
436447

437448
```ts
438449
navigator.queueBeacon(url, fetchOptions, beaconOptions): PendingBeacon
439450
```
440451

452+
This proposal gets rid of the `data` parameter, and request body should be put into `fetchOptions.body` directly.
453+
441454
The extra `beaconOptions` is a dictionary taking `backgroundTimeout` and `timeout` to support the optional timeout after bfcache or hidden requirement.
442455

443456
At the end, this proposal also requires an entirely new API, just under the existing `navigator` namespace. The advantage is that we might be able to merge this proposal into [w3c/beacon] and eliminate the burden to maintain a new spec.

0 commit comments

Comments
 (0)