12:02
<benjamingr_>
o/
12:02
<benjamingr_>
Hey, if someone has overwritten `fetch` in a web page is there any way to get a reference to the original?
12:03
<benjamingr_>
I know I can grab it from an `iframe` but that messes with the referrer, it's not transferrable so I can't move it from the worker (I can facade it, maybe - but would rather not)
12:08
<Ms2ger>
benjamingr_, can you grab the function from the iframe and then do other_fetch.call(window)?
12:09
<Ms2ger>
Not sure if that would work
12:09
<benjamingr_>
That would mess with the referrer header
12:10
<Ms2ger>
Then your only option is to beat whatever code is overwriting it to the punch
12:11
<benjamingr_>
Can't, other ideas welcome
12:12
<Ms2ger>
I don't think there's any
12:12
<Ms2ger>
Maybe Domenic has some
12:13
<benjamingr_>
Domenic is/was working on a getOriginals which would have solved this for me anyway - but that's still a long way away afaik
13:33
<Domenic>
That shouldn't mess with the referrer if you use . call
13:33
<benjamingr_>
Ah, interesting, why?
13:34
Domenic
is unsure what benjamingr_ thinks of as "long"
13:34
<Domenic>
It uses the this value to compute things
13:34
<benjamingr_>
Ah, fabulous, I had no idea - thanks
13:34
<benjamingr_>
"long" - not something I can use in a PoC I want to do "just so it's cool" in the next 2-3 months.
13:35
<Domenic>
Yeah 2-3 months is a tight constraint
13:36
<benjamingr_>
+ not one you should or would be interested in fulfilling just for my PoC :D
13:46
<benjamingr_>
It's a little surprising to me since I'd expect `fetch(url)` to behave similarly to `fetch.call(window, url)` since either fetch is unbound (which means it gets `window` by default as context in loose mode) or it is bound in which case I don't understand why `.call` sets its this.
13:46
<benjamingr_>
What am I missing Domenic?
13:50
<Domenic>
I don't understand the confusion. It's unbound. Which means you can change its this value with .call. but the default this value is indeed window. No contradiction.
13:51
<Domenic>
Notice that Ms2ger is specifically suggesting using otherFetch.call(window), to change the this value of otherFetch.
13:58
<benjamingr_>
https://www.irccloud.com/pastebin/qw9X1cpj/
13:59
<benjamingr_>
"No contradiction." - I don't understand that part - it's unbound, the default value is indeed window, but when `.call`ing it and setting it explicitly to `window` it sets the referrer.
14:05
<wanderview>
benjamingr_: do you get the same behavior in different browsers?
14:06
<benjamingr_>
I haven't tested. I'm 95% convinced that this is the fact I've been sick myself and dealing with a sick relative and that there is a reasonable reason for this like me not understanding `this` for APIs across contexts. I'll check
14:08
<Ms2ger>
I think it's at least as likely that some browsers use the wrong object
14:08
<benjamingr_>
wanderview - Firefox sends the referrer anyway.
14:09
<benjamingr_>
So Firefox and Chrome behave differently and Chrome's behavior deviates from my understanding of how `this` works in JavaScript. The problem is that I still don't know if I should open a crbug or bugzilla.
14:17
<wanderview>
benjamingr_: I don't see a WPT test for this, but maybe I'm just not finding it...
14:19
<benjamingr_>
I think I'll look into it some more and open an issue in the `fetch` repo, I still believe this is just sleep deprivation so I'm hesitant to spend more of other peoples' time
14:20
<wanderview>
sounds reasonable... thanks! (and I hope you and your relative feel better)
14:21
<benjamingr_>
I guess if `fetch` itself is in strict mode it can explicitly check the `.call` value and differentiate but still confusing. Thanks for helping - I will update!
14:21
<Domenic>
Imagine the following code: `otherWindow.fetch = (...args) => { const referrerToUse = this.document.URL; }`
14:21
<Domenic>
Then if you do `otherWindow.fetch(...)` it will use `otherWindow.document.URL` as the referrer
14:21
<Domenic>
But if you do `otherWindow.fetch.call(window, ...)` it will use `window.document.URL` as the referrer
14:22
<Domenic>
Thus, if you want to get a "clean" copy of fetch (i.e. `otherWindow.fetch`), but have it use the "normal" referrer as if you were using "normal" `window.fetch()`, it suffices to just do `otherWindow.fetch.call(window, ...)`
14:22
<benjamingr_>
I think I understand what I was missing - if I grab a function from another context then when invoking it the `this` value is set to the global object _of that realm_ rather than the one I'm in - that should have been obvious. Thanks Domenic!
14:25
<Ms2ger>
Domenic, how about let f = otherWindow.fetch; f()?
14:30
<benjamingr_>
Ms2ger: when you call `f` there it calls it with `otherWindow` as the `this` since that's the global of its environment
14:30
<Domenic>
No... that's not how this works.
14:31
<Domenic>
It'll call it with undefined as this. Which per Web IDL gets converted to `window`, I am pretty sure.
14:32
<Domenic>
Oh nope, per Web IDL it gets converted to `otherWindow`, it looks like.
14:32
<Domenic>
https://heycam.github.io/webidl/#dfn-create-operation-function 2.1.2.1
14:33
<Domenic>
`window` wouldn't have made sense anyway, nevermind. +1 benjamingr_.
14:35
<wanderview>
so does any browser dtrt?
14:36
<benjamingr_>
Well - Firefox is behaving differently by sending `Referrer` from an iframe when Chrome doesn't. Personally I like Chrome's behaviour better as a default and the only reason I need this "hack" is that there is nothing like `getOriginals` in the browser yet.
14:37
<benjamingr_>
Other things that would have helped - `fetch` being transferable, `ReadableStream` being transferable (that'd make the shim easy). They're both 'hacks' for what I really want (a clean reference I can rely on).
19:38
<TimothyGu>
benjamingr_: hmm, so what was the conclusion here? tbh I don't see anything in the spec for fetch() I'm reading that uses the `this` object in anyway
19:39
<TimothyGu>
The place where the referrer header gets set is step 2 in https://fetch.spec.whatwg.org/#dom-global-fetch, with the implication that "initial value of Request" refers to that in the realm for which this fetch() function was created
19:39
<benjamingr_>
Well, two things - first: Firefox and Chrome behave differently regarding the `Referer` header in iframes.
19:39
<TimothyGu>
Step 13 in https://fetch.spec.whatwg.org/#dom-request says the "current settings object" is used, which for fetch() means that of the realm it was created for
19:39
<TimothyGu>
Interesting
19:40
<benjamingr_>
Second, Chrome's `this` behaves differently than I expect in `fetch` (and not in accordance to which the `fetch` function was created). I really like this behaviour but only because it's the only way I have to get a safe `fetch` as an SDK
19:40
<TimothyGu>
I see...
19:42
<benjamingr_>
I'd expect a same origin iframe without a `src` set to send XHR and fetch exactly the same way as the parent document - but that's unrelated. Chrome doing Firefox's behavior would be great. Otherwise I'd have to grab `fetch` from a worker and since neither `ReadableStream` nor `fetch` itself is transferable that's quite a bit of work.
19:43
<TimothyGu>
Yeah, but having to create a whole new iframe just for a fetch() method (which prevents the iframe from being GC'd) is not that great
19:44
<TimothyGu>
If Firefox's fetch is bound to the window it was created for, I think that's the right behavior here
19:45
<benjamingr_>
Domenic posted a spec link explaining why it isn't IIRC
19:45
<benjamingr_>
Something about 2.1.2.1 https://heycam.github.io/webidl/#dfn-create-operation-function
19:46
<TimothyGu>
Yeah that has to do with how the `this` value is set
19:46
<TimothyGu>
But `fetch` doesn't (or shouldn't) use the `this` value at all
19:46
<Domenic>
Blargh
19:46
<Domenic>
I didn't actually check the spec, I just assumed it used the relevant global, because that's the guidance these days
19:47
<Domenic>
But TimothyGu's right that the behavior seems to happen implicitly in "the initial value of Request"
19:47
<Domenic>
So I think it should still be relevant (= realm of this) due to https://github.com/heycam/webidl/issues/135
19:47
<Domenic>
But it's borderline
19:48
<Domenic>
"invoking the initial value of the Response constructor" is different from what 135 is talking about, which is "a new Request object"
19:48
<Domenic>
It'd be hard to argue that the spec is clear here and any browser is specifically wrong
19:52
<benjamingr_>
I'm not sure Firefox behaves differently, just that it sends the `Referer` header anyway
19:52
<benjamingr_>
Any suggestions on how to check this welcome as the differing behavior in Chrome between `fetch` and `fetch.call(window` doesn't exist on Firefox as far as I know.
20:01
<Domenic>
Filed https://github.com/whatwg/fetch/issues/777
20:02
<Domenic>
It does seem like for practical purposes you may be in trouble here
20:02
<Domenic>
Even if in theory the spec gives you the tools you want