Bug 197779 - Using Web Share API preceded by an AJAX call
Summary: Using Web Share API preceded by an AJAX call
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit API (show other bugs)
Version: Safari 12
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Dumez
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-05-10 09:14 PDT by Mendel
Modified: 2020-01-07 17:07 PST (History)
14 users (show)

See Also:


Attachments
WIP Patch (7.52 KB, patch)
2020-01-07 09:04 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (19.51 KB, patch)
2020-01-07 10:04 PST, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mendel 2019-05-10 09:14:44 PDT
When users click the share button on our paywalled site, we generate a token via an async call that allows the people clicking on the share link to bypass the paywall.

I've added support for Web Share API first calling the token before triggering navigator.share - along these lines:

fetchCallForLink()
  .then((url) => {
    navigator.share({
      title: 'Test Title',
      url,
    });
This is working fine on Chrome / Android which supports Web Share.

However on Safari, I am getting a not allowed error.

>The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission

(This only happens on the first share attempt as I save the response to the window and therefore on subsequent clicks it avoids the AJAX call and works just fine.)

Because of the number of readers we have and the small number that actually use the share option, it would be expensive to make the AJAX call for ever page load (vs. only when user expresses intent to share).


Example: https://mkonikov.com/web-share-testing/ I've added a toggle to share with or without fetching first. This share fails only when fetch is enabled. (or with a setTimeout of over 1000ms - though as seen in the example, it fails immediately if share is preceded by an AJAX/fetch call)
Comment 1 Radar WebKit Bug Importer 2019-05-12 14:57:07 PDT
<rdar://problem/50708309>
Comment 2 Tim Horton 2019-05-13 09:05:55 PDT
This is likely the user-gesture check. Is that supposed to propagate through fetch()?
Comment 3 Mendel 2019-05-13 09:58:17 PDT
That is my assumption. Though I would hope there would be a way to propagate through the fetch (as is necessary in my situation)
Comment 4 Alex Christensen 2019-05-13 13:16:59 PDT
There is not a way to propagate a user gesture through fetch.
Comment 5 Mendel 2019-05-16 08:00:27 PDT
Is this a V1 implementation meant to be improved on?
I assume it's not against spec seeing it working in Chromium
Comment 6 Mendel 2019-06-11 13:51:56 PDT
Is it expected to remain that way?
Comment 7 Benjamin Schiller 2020-01-01 01:25:35 PST
Same problem on iOS 12.4. Need a ajax call before navigator.share. It's a disproportionate effort to query data beforehand.

It's working without problems on Chrome.
Comment 8 Mendel 2020-01-06 07:48:33 PST
Ya :(

Hoping there's a way to to get Safari in line with other browsers to allow an async call before navaigator.'sharing'
Comment 9 Chris Dumez 2020-01-06 08:10:59 PST
Spec says that the relevant global object should have *transient* activation:
[1] https://w3c.github.io/web-share/#dom-navigator-share
[2] https://html.spec.whatwg.org/multipage/interaction.html#transient-activation

So basically, for a certain amount of time after a user gesture, the API should work. If our implementation requires a user gesture, then it is not aligned with the spec.
Comment 10 Chris Dumez 2020-01-06 08:12:25 PST
(In reply to Chris Dumez from comment #9)
> Spec says that the relevant global object should have *transient* activation:
> [1] https://w3c.github.io/web-share/#dom-navigator-share
> [2]
> https://html.spec.whatwg.org/multipage/interaction.html#transient-activation
> 
> So basically, for a certain amount of time after a user gesture, the API
> should work. If our implementation requires a user gesture, then it is not
> aligned with the spec.

From Navigator::share():
    if (!UserGestureIndicator::processingUserGesture()) {
        promise->reject(NotAllowedError);
        return;
    }

This is not quite right indeed.
Comment 11 Chris Dumez 2020-01-06 08:15:32 PST
I can fix this.
Comment 12 Chris Dumez 2020-01-06 08:32:58 PST
(In reply to Chris Dumez from comment #11)
> I can fix this.

This apparently needs some internal discussion as the current behavior was intentional.
Comment 13 Mendel 2020-01-06 10:55:34 PST
Thank you Chris!
Comment 14 Chris Dumez 2020-01-07 09:04:47 PST
Created attachment 386977 [details]
WIP Patch
Comment 15 Chris Dumez 2020-01-07 10:04:44 PST
Created attachment 386983 [details]
Patch
Comment 16 WebKit Commit Bot 2020-01-07 17:07:33 PST
Comment on attachment 386983 [details]
Patch

Clearing flags on attachment: 386983

Committed r254178: <https://trac.webkit.org/changeset/254178>
Comment 17 WebKit Commit Bot 2020-01-07 17:07:35 PST
All reviewed patches have been landed.  Closing bug.