Re: [whatwg/fetch] Propagate URL fragments (#696)

@davidben commented on this pull request.



> @@ -3835,6 +3836,13 @@ these steps:
       </ul>
 
       <p>then return a <a>network error</a>.
+
+     <li>
+      <p>Set <var>actualResponse</var>'s <a for=response>URL</a>'s <a for=url>fragment</a> to
+      <var>request</var>'s <a for=request>current URL</a>'s <a for=url>fragment</a>.
+
+      <p class=note>There is currently no mechanism for the service worker to control
+      <var>actualResponse</var>'s <a for=response>URL</a>'s <a for=url>fragment</a>.

(@wanderview is probably a better person to answer what we're willing to experiment with. I don't actually work on service worker stuff. I'm just really distractible and like to stick my nose into everything. Although I see I'm rapidly becoming "the redirect person" which is... a life decision. 😄)

I was pondering other ideas, and they broke on this case, so probably something to include in tests. Suppose the server responds to requests as follows:

GET /a => 302; Location: /b#foo
GET /b => 302; Location: /c
GET /c => 200

We'd want `fetch("/a")` to get a redirect path of /a -> /b#foo -> /c#foo. That implies that the fragment fixup logic needs to be part of `{redirect: "follow"}` and not something we only apply to the final response. However, `fetch("/a#foo")` would then go /a#foo -> /b#foo -> /c#foo and there isn't enough information to know whether c's fragment was intrinsic or came from the request fragment. That means any caching fetch intermediary must store the result of a fragment-less fetch. Otherwise you lose information and cannot correctly share cache entries between /a#foo and /a#bar.

Also, all this relies on it being impossible for the server to redirect and *remove* a fragment. (If the server sends a fragment-less location header, we fill in the request URL's fragment.) If it were possible, we'd need to store extra information in the response. That is, if the server says:

GET /a => 302; Location: /b#:magic-syntax-to-remove-fragment

Then we have /a -> /b, but also /a#foo -> /b, but that conflicts with the "When we consume a SW-forwarded response, [...]" logic. We'd need responses to store an extra copyFragmentFromRequestURL boolean.

To that end, that does suggest one more possible model which doesn't need to change FetchEvent:

* Responses have a "copy fragment from request URL" boolean property
* SW still sees the fragment and are allowed to fetch as before
* Fetch sets the new property to true if every Location header we followed was fragment-agnostic
* When you get a response from a SW, clobber the fragment if that property is true.

But this one seems even more fussy and probably isn't what we want. Yet another possibility would be to move the fragment fixup logic from FetchEvent.respondWith() to CacheStorage. Something like:

* Responses track whether fragments came from the request URL or not as above.
* When you serialize a response, don't serialize fragments that came from the request URL, only intrinsic ones.
* When you get a response out from CacheStorage.match(), apply the fragment fixup logic.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/pull/696#discussion_r578543960

Received on Thursday, 18 February 2021 16:07:21 UTC