-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
It's possible for a request for an image to receive a 404 response that has an image Content-Type with valid image data attached, to be displayed as a placeholder. Currently, img
elements are required to display this placeholder data (per 4.8.4.3 Processing Model):
Whether the image is fetched successfully or not (e.g. whether the response status was an ok status) must be ignored when determining the image's type and whether it is a valid image.
What's less clear is how this should apply to the case of picture
elements with a list of source
s, when one of those sources fails with a placeholder 404 image.
The status quo
My understanding of the spec is that if a source
fails with a 404, regardless of whether placeholder data is received, the browser is supposed to try the next source
in the list:
- The media resource selection algorithm, step 9, case children, sub-step 8 requires that the
source
's target resource be fetched using the resource fetch algorithm. - The resource fetch algorithm, step 4, case remote, sub-step 8, sub-sub-step 4 requires that the network request used to fetch the resource be verified. Verification fails if the internal response's status code is not 200 or 206.
- Some of the steps around there link to the HTTP fetch standard; I dug around and didn't find anything in that standard that would result in the browser "lying" about a 404 request with placeholder data not being a 404. Looking at the HTTP-network fetch steps, it seems like the server's original status code is applied to the response directly, at least for codes outside the [100, 199] range.
- If the resource fetch algorithm fails, then the media resource selection algorithm, step 9, case children will not be aborted at sub-step 8, and so will continue to the next steps, which involve moving onto the next
source
(if any) and trying that one.
It seems that the spec-compliant behavior would be:
- If a
source
fails with a 404, try the nextsource
, regardless of whether the failingsource
had placeholder image data attached to the 404 response. - If all
source
s fail, and theimg
also fails, then use only any placeholder image data attached to theimg
's 404 response. If theimg
404 response did not contain placeholder data, then display a broken image (i.e. no placeholder data from anysource
will be used).
Current browser behavior
If Chromium and Mozilla Firefox encounter a source
that 404s with placeholder content, they will display that placeholder content, instead of making any attempt to try the next source(s) in the list. Additionally, neither browser makes any attempt to try more than the first source
with a supported MIME type. Consider the code below:
<!doctype html>
<html>
<body>
<picture>
<!-- <source srcset="https://example.com/nonexistent.png" type="image/jpeg" /> -->
<source srcset="https://i.ytimg.com/vi/asdf/nonexistent.jpg" type="image/jpeg" />
<source srcset="https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" type="image/jpeg" />
<source srcset="https://i.ytimg.com/vi/dQw4w9WgXcQ/sddefault.jpg" type="image/jpeg" />
<img set="https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg" />
</picture>
</body>
</html>
We are here trying to display the YouTube thumbnail for Rick Astley's "Never Gonna Give You Up." There are multiple possible URLs for a YouTube thumbnail, and not all such URLs are available for every video; additionally, if any image request to the YouTube thumbnail server fails, the server returns a 404 response with a 120x90px image/jpeg
placeholder attached. This placeholder is what the above code displays in Firefox and Chromium. If we uncomment the obviously broken example.com
URL, then Firefox and Chromium just display a broken image; watching the network requests allows us to see that they never attempt to request anything else after failing to load nonexistent.png
.
It seems, then, like a key portion of the spec for picture
and source
elements is completely unimplemented in every major browser.
So I guess my questions are...
-
Should the spec be amended to match existing browser behavior? It seems like it'd be far more useful if web browsers actually implemented the "try each source until one works" part of the spec instead.
-
Suppose that web browsers were to ignore 404 placeholder data on a
source
: if asource
404s, the browser tries the nextsource
or, if none remain, theimg
, instead of just displaying any placeholder data that was sent along with the 404.If all
source
s fail, theimg
also fails, and one or moresource
s had placeholder data, then should the spec be amended to have the browser display one of thosesource
s' placeholders? Should the browser prefer the earliestsource
in the list that had a placeholder? Should the browser prefer theimg
placeholder, if one was received, over allsource
placeholders?I don't know terribly much about how network requests are done under the hood, but I'd imagine that if browsers can use the earliest placeholder in the list, then they don't have to actually bother to fully load the placeholders for any failing
source
elements after that one. -
...Am I even interpreting these parts of the spec properly to begin with?