fetch icon indicating copy to clipboard operation
fetch copied to clipboard

Accept headers in spec cause confusion

Open yoavweiss opened this issue 9 years ago • 31 comments

During recent Chrome patch discussions, concerns were raised that Chrome's Accept headers are not spec compliant, as they include MIME types supported by Chrome but not supported universally. While that's not the case, it required explanations as to why our current implementation is as it should be. I think a note in the spec would go a long way to prevent similar cases in the future.

This was raised in the past, but was concluded as unnecessary. I agree with past arguments that current spec language permits UAs to extend the Accept header, but stating it explicitly, saying that user agents may (or even should) extend the spec's values with MIME types they support, would be helpful.

/cc @igrigorik

yoavweiss avatar Apr 06 '16 12:04 yoavweiss

Relevant part of the spec is 5 Fetching.

See also this mozilla bug, which moved them to */* for images. It gives some rationale for how to manage these values.

mnot avatar Apr 06 '16 15:04 mnot

Yeah, some of that bug should probably become a "Background reading" section. No objections from me to further clarifying this.

And I guess we should update image to be */* since that's now more common.

annevk avatar Apr 06 '16 17:04 annevk

Updating image to be */* would also solve the "what to do for <img src="foo.mp4">" problem.

cc @jernoble @grorg

hober avatar Dec 05 '17 21:12 hober

To me the right framework seems to be mandating */* but then allowing browsers to add others on the end if they want? It seems like we shouldn't lock down the image formats the web supports, in general... Or should we try to converge on that too, these days?

domenic avatar Dec 05 '17 22:12 domenic

Ideally they are added just like other features I think, but IPR complicates media formats tremendously. So maybe that's a reasonable way to go.

annevk avatar Dec 06 '17 18:12 annevk

To me the right framework seems to be mandating / but then allowing browsers to add others on the end if they want? @domenic

Agreed! I do remember seeing on the chromium bug someone stating "the spec shouldn't define Accept." Not certain I agree but I do feel */* with the ability to extend is a win, win.

Very Postel's Law. Worked for TCP :-)

@annevk can you clarify "they"? Not sure of context.

snuggs avatar Mar 15 '18 15:03 snuggs

FWIW - */* is always implied; they only reason you'd want to include it explicitly is if you want to say */*;q=0 -- i.e., "don't send me anything else."

mnot avatar Mar 15 '18 15:03 mnot

Thanks for the clarification @mnot! 🙏

Also been meaning to ask for a while now but didn't know the place as the context is spread between WHATWG & W3C and all places in between.

Regards to preloading (therefore fetch destinations) Am curious of Accept for the document destination. Although I'm not versed on how fetch works with frame documents. I do realize there is a bug in chrome for link as=document not working. I noticed as=script and as=fetch all use */*. However as=font and as=style send Accept similar to browser defaults. would document send the default UA Accept: text/html,...,*/*;q=0.9 or */*? I think it should be the former of the two.

This has been a concern for me in keeping MDN docs up to date as am noticing documentation is already starting to send out (potentially) incorrect information and there are links from the documentation back to here for "a bit more detail".

preload has other advantages too. Using as to specify the type of content to be preloaded allows the browser to:

Prioritize resource loading more accurately. Match future requests, reusing the same resource if appropriate. Apply the correct content security policy to the resource. Set the correct Accept request headers for it.

"correct" is the word that concerns me and who defines it.

Please forgive me if this is a vendor specific topic similar to as=document but I feel some vendor specific (and relative to myself, documentation) topics we can aid a touch with proactive avoidance AKA a touch more granular clarification within the spec.

Thanks in advance to whoever has information! I feel this is a relative place to ask. Please direct me elsewhere if this is not the place. Wanted to spare yet another issue. This as been a mystery to me for months since the feature is broken at the vendor I use to test.

snuggs avatar Mar 15 '18 15:03 snuggs

@snuggs - <link rel=preload as=document> is not currently supported in Chromium, as supporting it is more likely in the current prioritization scheme is more likely to be a footgun than anything else. But please comment on the issue you linked to if you have feedback on that.

"correct" in the documentation most likely refers to the fact that the browser is aware of the Request.destination for the resource it is fetching and therefore can adapt the Accept value to that.

If you think some browsers are not sending the right Accept headers for preloads vs. regular fetches of the same request destinations, implementation bugs are probably in order.

yoavweiss avatar Mar 15 '18 16:03 yoavweiss

Hmmm @yoavweiss not certain i'm versed well enough on this topic to even give feedback. Still fairly new here. I do realize we push back on things conneg-y. However I feel much of the pain (and failure) in the past was much to do with conversations like this not being had during implementations (or being had behind respective vendor closed mail threads). Much has changed since then and specs (usually) are sound. It's the unclear assumption during implementation is the loading of the magazine in said footgun IMHO. The WPT does help with these assumptions today but I could not find relevant tests there (i've checked).

Perhaps this is less of a deal than I think this is. You all would know better. However during this transition to a more collaborative web I'm learning (from @domenic) That's just the way we've done things around here. Is ok to question from time to time. As long as the question doesn't break the web of course. 😄 That's the part i'm still figuring out.

Is this even a concern @yoavweiss or are there better fish to fry?

Thanks for the feedback and your time.

snuggs avatar Mar 15 '18 16:03 snuggs

@snuggs - apologies if my reply came across as overly-negative. That wasn't my intention.

I do realize we push back on things conneg-y.

I don't know that this is still true in general. It certainly isn't true for my specific case. And we have been pushing improved content negotiation solutions in the last few years.

Is this even a concern @yoavweiss or are there better fish to fry?

I'm not sure what you're referring to by "this". IMO, "correct" and useful Accept headers are certainly something worth investing time and thought in. I don't think we need to specify what the value of those headers is for all request destinations, because support varies between different browsers and implementations. Therefore I believe the spec needs to give implementations the liberty (and guidance) to do what's right. Unlike today, where implementations need to ignore a SHOULD in order to truly advertise their support for non-universal file formats.

Regarding fetch vs.script destinations, do you have a use case in mind where differentiating the two would be helpful? What are the Accept header values for them when not considering preload?

yoavweiss avatar Mar 15 '18 16:03 yoavweiss

And we have been pushing improved content negotiation solutions in the last few years. @yoavweiss

I feel a ton better about my thoughts on the matter. Wish I would have seen that years ago.

Regarding fetch vs.script destinations, do you have a use case in mind where differentiating the two would be helpful? What are the Accept header values for them when not considering preload?

To be clear I have no issue with fetch & script sending */* all across the board. IIRC @domenic mentioned a needle in some haystack here about mime types only being needed to discern whether or not to block a script. I think related to image vs '*' and being able to be executed. As I think more there are a couple congruent thoughts.

  1. What is the value of Accept on a per-case requested resource destination basis which I am much clearer on from this issue and the places you all are linking me to. (wasn't my initial concern but interested now).
  2. Can/should the Accept be the same as the browser does now. (elaboration below).

Navigating to a url seems to give a consistent Accept Based on this MDN documentation. Would the correct term we use be "Browsing context"? I noticed that somewhere before. Also feel the term in the document "default" is really related to */* perhaps? Am understanding using the address bar/ <a href=...> (browsing context(?)) is the "default" for end users. IMHO better stated as "most commonly used by humans but browsers aren't humans.". Also states

Browsers add the */*. Going off our discussion the inverse would be true. The spec defaults the browser to */* and each can add at their discretion. Would personally love to have document request destination send more than */*.

My use case is am currently preloading some html. Due to as=document not working (which seems more semantically correct than fetch and at the time months ago didn't know this was a personal problem of Chrome's) we began using <link rel=preload as=fetch> to circumvent the bug. We do some light logging internally via Accept and although technically an html file and javascript file are indeed "text" (as @annevk pointed out to me earlier today). I do feel if there is a chance we can take to have as=document (or document destination) be "browsing context" or whatever makes that default Accept. I think this is the place to at least start the conversation. I do not know how this affects XMLHTTPRequest tho.

P.S. ** note to self ** Use this, that, it, etc. less on Github. * This * (pun intended) is the second time someone mentioned to me. :-)

snuggs avatar Mar 15 '18 17:03 snuggs

@yoavweiss I think I found what/where i've been looking for:

https://fetch.spec.whatwg.org/#fetching

Step 3.3

... Otherwise, a user agent should set value to the first matching statement, if any, switching on request’s destination:

"image" image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5 "style" text/css,*/*;q=0.1

Is this list not exhaustive? Should the spec include document etc? Is this where we run into issues when Firefox changes image to */*?

snuggs avatar Mar 15 '18 19:03 snuggs

document is covered by the previous clause:

If request is a navigation request, a user agent should set value to text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8.

But otherwise, the list is not exhaustive. This issue is about making sure that this list enables user agents to maintain useful Accept header values that match their supported formats, while staying spec compliant.

yoavweiss avatar Mar 15 '18 21:03 yoavweiss

@yoavweiss Just an update from a question I asked you earlier about document destination related to Chrome. i don't know if "Main Frame" means browsing context but I do see where the document destination would be set which was addressed in this patch. Would be able to test if as=document worked for Chrome. But alas... Thanks for the input and apologize if diverted the issue. I believed the topic was relative from searching issues. And I know now where to track these topics and bugs.

Thanks for your help.

snuggs avatar Mar 16 '18 00:03 snuggs

So I looked at this again, for the img element:

  • Firefox: image/webp,*/*
  • Safari: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
  • Chrome: image/webp,image/apng,image/*,*/*;q=0.8

And Fetch still has image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5, matching nobody, though it's a "should", not a "must".

I guess we can say something about using */* when in doubt and something matching the Accept production otherwise, unless there's a desire from user agents to align here.

annevk avatar Oct 23 '19 15:10 annevk

As long as different user agents support different file formats it doesn't make sense to align here. For example, I think that nowadays Firefox and Chrome could align with each other, but they shouldn't align with Safari as long as Safari doesn't support webp and does support videos in image contexts.

What Fetch could do is provide general guidance about how UAs should construct their Accept strings (e.g. have the "rarest" supported format first, collapse commonly supported values into "/", etc), but I don't think the spec should dictate any specific values.

That is, unless we want to define precise processing ("if webp is supported, apng is supported, and video formats in image contexts are not supported, return ...." kind of definition).

Does that make sense?

yoavweiss avatar Oct 24 '19 07:10 yoavweiss

I'm not sure, Chrome expanding the Accept header for navigations creates a mess such as https://bugzilla.mozilla.org/show_bug.cgi?id=1544231. And ideally addition of formats goes through a similar process as adding new features, at which point a decision about the new header could be made as well.

annevk avatar Oct 24 '19 09:10 annevk

From #877

This should be adapted to give user agents the possibility to include image formats that might not be universally accepted but preferred, e.g. image/webp or image/apng or image/jxr, and to exclude formats that might not be supported or preferred (e.g. excluding svg support for agents on systems where vector graphics are disproportionately expensive to process), to allow server-driven conneg to happen with servers that support multiple other formats.

As it stands, the spec doesn't allow for this kind of required flexibility, since it creates the expectation that all user agent should align, and users agents would not be spec compliant if they indicate their capabilities to servers which is in many situations desired. What's the point of the Accept headers if you're not actually allowed to use them for what they are for?

wolfbeast avatar Oct 24 '19 09:10 wolfbeast

I'm not sure, Chrome expanding the Accept header for navigations creates a mess such as https://bugzilla.mozilla.org/show_bug.cgi?id=1544231.

Speaking only for myself (haven't asked around yet), I think it may make sense to define what Accept headers values are given a set of supported formats. The main risk is that the definition may get verbose/complex as the number of permutations gets higher.

At the same time, I wouldn't want Safari to "align" their Accept values before they actually support the underlying formats.

P.S. On the cited issue, I'd argue that Firefox should add webp support to its navigation Accept values, to enable negotiation of image documents.

yoavweiss avatar Oct 24 '19 09:10 yoavweiss

Negotiation of image documents is not what it is being used for. The issues Firefox hits are because sites are using the Accept header to figure out what HTML to generate, which is not what the feature is for.

annevk avatar Nov 04 '19 14:11 annevk

That's not a problem with the spec. Mandating certain fixed strings in the spec to passive-aggressively force website owners to use other methods for browser detection (which is what you're saying, IIUC) is the wrong approach to this problem, especially if you're breaking valid content negotiation mechanisms in the process.

wolfbeast avatar Nov 04 '19 14:11 wolfbeast

Hi folks,

We recently changed Firefox to Remove image mime types from document accept header in order to match the fetch spec. After doing so, we got some push back:

  • Sites using the document Accept header to decide which image formats to include in the document could no longer do so.
  • Navigating to an image URL can't negotiate content type, because image formats are no longer present in the document accept header. see bug 1950012

I agree with @annevk that the document accept header shouldn't be used to negotiate image content types - since there's no guarantee that the same content-types will be present in the image request's Accept header.

I think the second issue is trickier. Since the browser doesn't know whether a document load is to an image or a HTML file ahead of time, it will always send the same document accept header. In order to enable content type negotiation this would suggest that image mime types should be part of the document accept header. But this might be an avenue for future bloat, because you can make the same argument for audio, video, and other types of content. Should we include all of them in the document accept header? 🤷

Thoughts?

valenting avatar Mar 20 '25 09:03 valenting

  • Sites using the document Accept header to decide which image formats to include in the document could no longer do so.

I agree such sites are better off using e.g. the <picture> element to include all the options, or server-side content negotiation for the images themselves.

I think the second issue is trickier. Since the browser doesn't know whether a document load is to an image or a HTML file ahead of time, it will always send the same document accept header. In order to enable content type negotiation this would suggest that image mime types should be part of the document accept header. But this might be an avenue for future bloat, because you can make the same argument for audio, video, and other types of content. Should we include all of them in the document accept header? 🤷

I think we probably should send the mime types for all of these, or at least the ones that are not ubiquitously supported. I think it'd be interesting to see what the different implementations are doing, try to align and then document that in the spec.

yoavweiss avatar Apr 30 '25 07:04 yoavweiss

I think we probably should send the mime types for all of these, or at least the ones that are not ubiquitously supported.

This sounds like a good approach to me. Most implementations are pretty well-aligned in what is "ubiquitous", I think. Personally, I think only the following types have varying support in browsers (especially when it comes to top-level navigation):

  • image/avif
  • image/jxl
  • image/webp (maybe?)
  • video/x-matroska
  • video/webm (maybe?)

AFAIK types like png, jpg, gif, mp4, avi, ogg, aac, flac have full support everywhere, but please correct me if I'm wrong. If webp and webm are considered ubiquitous then the amount of header size increase is even less. Media/image support does not change often and adoption tends to be slow, warranting at least some time where explicit Accept: entries are added.

wolfbeast avatar May 01 '25 14:05 wolfbeast

@annevk - thoughts on the above? If you're supportive, I can try to find the time to take a stab at this

yoavweiss avatar Aug 25 '25 08:08 yoavweiss

It would help to have a summary of what exactly we want to change at this point (some of the Accept headers I believe should not be changed, such as the one for "json"), what the status quo is for that particular request destination/type across existing user agents, and what it would be changed to.

annevk avatar Sep 09 '25 14:09 annevk

I think https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Content_negotiation/List_of_default_Accept_values is still accurate.

valenting avatar Sep 17 '25 07:09 valenting

Our (UXP/Goanna/Pale Moon) headers are currently:

Navigation requests: text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/webp,image/apng,video/x-matroska,video/webm,*/*;q=0.8 Image requests (IMG elements etc.): image/jxl,image/webp,image/apng,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5 Stylesheet requests: text/css,*/*;q=0.1

For other requests we fall back to */*

What we consider ubiquitous formats (jpeg, gif, mp4, etc) aren't presented in Accept headers.

Of note: we do not support AVIF so that format isn't in the headers, and we have full support for jpeg-XL so that is present.

wolfbeast avatar Sep 17 '25 10:09 wolfbeast

@valenting that's helpful, but that addresses only a third of what I was asking for.

annevk avatar Sep 17 '25 11:09 annevk