diff --git a/files/en-us/web/http/authentication/index.html b/files/en-us/web/http/authentication/index.html deleted file mode 100644 index 4b55c032e4f18d3..000000000000000 --- a/files/en-us/web/http/authentication/index.html +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: HTTP authentication -slug: Web/HTTP/Authentication -tags: - - Access Control - - Authentication - - Guide - - HTTP - - Security ---- -
HTTP provides a general framework for access control and authentication. This page is an introduction to the HTTP framework for authentication, and shows how to restrict access to your server using the HTTP "Basic" schema.
- -{{RFC("7235")}} defines the HTTP authentication framework, which can be used by a server to {{glossary("challenge")}} a client request, and by a client to provide authentication information.
- -The challenge and response flow works like this:
- -Authorization
header.In the case of a "Basic" authentication like shown in the figure, the exchange must happen over an HTTPS (TLS) connection to be secure.
- -The same challenge and response mechanism can be used for proxy authentication. As both resource authentication and proxy authentication can coexist, a different set of headers and status codes is needed. In the case of proxies, the challenging status code is {{HTTPStatus("407")}} (Proxy Authentication Required), the {{HTTPHeader("Proxy-Authenticate")}} response header contains at least one challenge applicable to the proxy, and the {{HTTPHeader("Proxy-Authorization")}} request header is used for providing the credentials to the proxy server.
- -If a (proxy) server receives invalid credentials, it should respond with a {{HTTPStatus("401")}} Unauthorized
or with a {{HTTPStatus("407")}} Proxy Authentication Required
, and the user may send a new request or replace the {{HTTPHeader("Authorization")}} header field.
If a (proxy) server receives valid credentials that are inadequate to access a given resource, the server should respond with the {{HTTPStatus("403")}} Forbidden
status code. Unlike {{HTTPStatus("401")}} Unauthorized
or {{HTTPStatus("407")}} Proxy Authentication Required
, authentication is impossible for this user and browsers will not propose a new attempt.
In all cases, the server may prefer returning a {{HTTPStatus("404")}} Not Found
status code, to hide the existence of the page to a user without adequate privileges or not correctly authenticated.
A potential security hole recently been fixed by browsers is authentication of cross-site images. From Firefox 59 onwards, image resources loaded from different origins to the current document are no longer able to trigger HTTP authentication dialogs ({{bug(1423146)}}), preventing user credentials being stolen if attackers were able to embed an arbitrary image into a third-party page.
- -Browsers use utf-8
encoding for usernames and passwords.
Firefox once used ISO-8859-1
, but changed to utf-8
for parity with other browsers and to avoid potential problems as described in {{bug(1419658)}}.
The {{HTTPHeader("WWW-Authenticate")}} and {{HTTPHeader("Proxy-Authenticate")}} response headers define the authentication method that should be used to gain access to a resource. They must specify which authentication scheme is used, so that the client that wishes to authorize knows how to provide the credentials.
- -The syntax for these headers is the following:
- -WWW-Authenticate: <type> realm=<realm> -Proxy-Authenticate: <type> realm=<realm> -- -
Here, <type>
is the authentication scheme ("Basic" is the most common scheme and introduced below). The realm is used to describe the protected area or to indicate the scope of protection. This could be a message like "Access to the staging site" or similar, so that the user knows to which space they are trying to get access to.
The {{HTTPHeader("Authorization")}} and {{HTTPHeader("Proxy-Authorization")}} request headers contain the credentials to authenticate a user agent with a (proxy) server. Here, the <type>
is needed again followed by the credentials, which can be encoded or encrypted depending on which authentication scheme is used.
Authorization: <type> <credentials> -Proxy-Authorization: <type> <credentials> -- -
The general HTTP authentication framework is used by several authentication schemes. Schemes can differ in security strength and in their availability in client or server software.
- -The most common authentication scheme is the "Basic" authentication scheme, which is introduced in more detail below. IANA maintains a list of authentication schemes, but there are other schemes offered by host services, such as Amazon AWS. Common authentication schemes include:
- -The "Basic" HTTP authentication scheme is defined in {{rfc(7617)}}, which transmits credentials as user ID/password pairs, encoded using base64.
- -As the user ID and password are passed over the network as clear text (it is base64 encoded, but base64 is a reversible encoding), the basic authentication scheme is not secure. HTTPS/TLS should be used with basic authentication. Without these additional security enhancements, basic authentication should not be used to protect sensitive or valuable information.
- -To password-protect a directory on an Apache server, you will need a .htaccess
and a .htpasswd
file.
The .htaccess
file typically looks like this:
AuthType Basic -AuthName "Access to the staging site" -AuthUserFile /path/to/.htpasswd -Require valid-user- -
The .htaccess
file references a .htpasswd
file in which each line consists of a username and a password separated by a colon (:
). You cannot see the actual passwords as they are hashed (using MD5-based hashing, in this case). Note that you can name your .htpasswd
file differently if you like, but keep in mind this file shouldn't be accessible to anyone. (Apache is usually configured to prevent access to .ht*
files).
aladdin:$apr1$ZjTqBB3f$IF9gdYAGlMrs2fuINjHsz. -user2:$apr1$O04r.y2H$/vEkesPhVInBByJUkXitA/ -- -
For nginx, you will need to specify a location that you are going to protect and the auth_basic
directive that provides the name to the password-protected area. The auth_basic_user_file
directive then points to a .htpasswd
file containing the encrypted user credentials, just like in the Apache example above.
location /status { - auth_basic "Access to the staging site"; - auth_basic_user_file /etc/apache2/.htpasswd; -}- -
Many clients also let you avoid the login prompt by using an encoded URL containing the username and the password like this:
- -https://username:password@www.example.com/- -
The use of these URLs is deprecated. In Chrome, the username:password@
part in URLs is even stripped out for security reasons. In Firefox, it is checked if the site actually requires authentication and if not, Firefox will warn the user with a prompt "You are about to log in to the site “www.example.com” with the username “username”, but the website does not require authentication. This may be an attempt to trick you."
A recurring question among website owners is whether to choose non-www or www URLs. This page provides some advice on what's best.
- -In an HTTP URL, the first substring that follows the initial http://
or https://
is called the domain name. This domain name is hosted on a server where the document resides.
A server isn't necessarily a physical machine: several servers can reside on the same physical machine. Or, one server can be handled by several machines, cooperating to produce the answer or balancing the load of the requests between them. The key point is that semantically one domain name represents one single server.
- -So, choose one of your domains as your canonical one! There are two techniques below to allow the non-canonical domain to work still.
- -There are different ways to choose which website is canonical.
- -In this case, you need to configure the server receiving the HTTP requests (which is most likely the same for www and non-www URLs) to respond with an adequate HTTP {{HTTPStatus(301)}} response to any request to the non-canonical domain. This will redirect the browser trying to access the non-canonical URLs to their canonical equivalent. For example, if you've chosen to use non-www URLs as the canonical type, you should redirect all www URLs to their equivalent URL without the www.
- -Example:
- -http://www.example.org/whaddup
(when the canonical domain is example.org){{HTTPHeader("Location")}}: http://example.org/whaddup
.http://example.org/whatddup
The HTML5 boilerplate project has an example on how to configure an Apache server to redirect one domain to the other.
- -<link rel="canonical">
It is possible to add a special HTML {{HTMLElement("link")}} element to a page to indicate what the canonical address of a page is. This has no impact on the human reader of the page, but tells search engine crawlers where the page actually lives. This way, search engines don't index the same page several times, potentially leading to it being considered as duplicate content or spam, and even removing or lowering your page from the search engine result pages.
- -When adding such a tag, you serve the same content for both domains, telling search engines which URL is canonical. In the previous example, http://www.example.org/whaddup
would serve the same content as http://example.org/whaddup
, but with an additional {{htmlelement("link")}} element in the head:
<link href="http://example.org/whaddup" rel="canonical">
Unlike the previous case, browser history will consider non-www and www URLs as independent entries.
- -With these techniques, you can configure your server to respond correctly for both, the www-prefixed and the non-www-prefixed domains. It is good advice to do this since you can't predict which URL users will type in their browser's URL bar. It is a matter of choosing which type you want to use as your canonical location, then redirecting the other type to it.
- -This is a very subjective topic it could be considered a bikeshedding issue. If you wish to read deeper, please see some of the many articles on the subject.
- -Data URLs, URLs prefixed with the data:
scheme, allow content creators to embed small files inline in documents. They were formerly known as "data URIs" until that name was retired by the WHATWG.
Note: Data URLs are treated as unique opaque origins by modern browsers, rather than inheriting the origin of the settings object responsible for the navigation.
-Data URLs are composed of four parts: a prefix (data:
), a MIME type indicating the type of data, an optional base64
token if non-textual, and the data itself:
data:[<mediatype>][;base64],<data> -- -
The mediatype
is a MIME type string, such as 'image/jpeg'
for a JPEG image file. If omitted, defaults to text/plain;charset=US-ASCII
If the data contains characters defined in RFC 3986 as reserved characters, or contains space characters, newline characters, or other non-printing characters, those characters must be percent-encoded (aka “URL-encoded”).
- -If the data is textual, you can embed the text (using the appropriate entities or escapes based on the enclosing document's type). Otherwise, you can specify base64
to embed base64-encoded binary data. You can find more info on MIME types here and here.
A few examples:
- -data:,Hello%2C%20World%21
Hello, World!
. Note how the comma is percent-encoded as %2C
, and the space character as %20
.data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==
data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E
<h1>Hello, World!</h1>
data:text/html,<script>alert('hi');</script>
Base64 is a group of binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. By consisting only in ASCII characters, base64 strings are generally url-safe, and that's why they can be used to encode data in Data URLs.
- -The Web APIs have native methods to encode or decode to base64: Base64 encoding and decoding.
- -Base64 encoding of a file or string on Linux and Mac OS X systems can be achieved using the command-line base64
(or, as an alternative, the uuencode
utility with -m
argument).
echo -n hello|base64 -# outputs to console: aGVsbG8= - -echo -n hello>a.txt -base64 a.txt -# outputs to console: aGVsbG8= - -base64 a.txt>b.txt -# outputs to file b.txt: aGVsbG8= -- -
On Windows, Convert.ToBase64String from PowerShell can be used to perform the Base64 encoding:
- -[convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("hello")) -# outputs to console: aGVsbG8= -- -
Alternatively, a GNU/Linux shell (such as WSL) provides the utility base64
:
bash$ echo -n hello | base64 -# outputs to console: aGVsbG8= -- -
This section describes problems that commonly occur when creating and using data
URLs.
data:text/html,lots of text...<p><a name%3D"bottom">bottom</a>?arg=val -- -
This represents an HTML resource whose contents are:
- -lots of text...<p><a name="bottom">bottom</a>?arg=val -- -
data
URLs is very simple, but it's easy to forget to put a comma before the "data" segment, or to incorrectly encode the data into base64 format.data
URL provides a file within a file, which can potentially be very wide relative to the width of the enclosing document. As a URL, the data
should be formatable with whitespace (linefeed, tab, or spaces), but there are practical issues that arise when using base64 encoding.data
URLs of essentially unlimited length, browsers are not required to support any particular maximum length of data. For example, the Opera 11 browser limited URLs to 65535 characters long which limits data
URLs to 65529 characters (65529 characters being the length of the encoded data, not the source, if you use the plain data:
, without specifying a MIME type).'base64'
, are ignored, but no error is provided.The data portion of a data URL is opaque, so an attempt to use a query string (page-specific parameters, with the syntax <url>?parameter-data
) with a data URL will just include the query string in the data the URL represents.
data://
URLs has been blocked in Firefox 59+ (release version, Nightly/Beta from 58), and we hope to see other browsers follow suit soon. See Blocking Top-Level Navigations to data URLs for Firefox 58 for more details.Specification | -Title | -
---|---|
{{RFC("2397")}} | -The "data" URL scheme | -
{{compat}}
- -url()
bottom?arg=val +``` + +This represents an HTML resource whose contents are: + +```html +lots of text...
bottom?arg=val
+```
+
+- Syntax
+ - : The format for `data` URLs is very simple, but it's easy to forget to put a comma before the "data" segment, or to incorrectly encode the data into base64 format.
+- Formatting in HTML
+ - : A `data` URL provides a file within a file, which can potentially be very wide relative to the width of the enclosing document. As a URL, the `data` should be formatable with whitespace (linefeed, tab, or spaces), but there are practical issues that arise [when using base64 encoding](https://bugzilla.mozilla.org/show_bug.cgi?id=73026#c12).
+- Length limitations
+ - : Although Firefox supports `data` URLs of essentially unlimited length, browsers are not required to support any particular maximum length of data. For example, the Opera 11 browser limited URLs to 65535 characters long which limits `data` URLs to 65529 characters (65529 characters being the length of the encoded data, not the source, if you use the plain `data:`, without specifying a MIME type).
+- Lack of error handling
+ - : Invalid parameters in media, or typos when specifying `'base64'`, are ignored, but no error is provided.
+- No support for query strings, etc.
+ - : The data portion of a data URL is opaque, so an attempt to use a query string (page-specific parameters, with the syntax ` HTTP (HyperText Transfer Protocol) is the underlying protocol of the World Wide Web. Developed by Tim Berners-Lee and his team between 1989-1991, HTTP has seen many changes, keeping most of the simplicity and further shaping its flexibility. HTTP has evolved from an early protocol to exchange files in a semi-trusted laboratory environment, to the modern maze of the Internet, now carrying images, videos in high resolution and 3D. In 1989, while he was working at CERN, Tim Berners-Lee wrote a proposal to build a hypertext system over the Internet. Initially calling it the Mesh, it was later renamed to World Wide Web during its implementation in 1990. Built over the existing TCP and IP protocols, it consisted of 4 building blocks: These four building blocks were completed by the end of 1990, and the first servers were already running outside of CERN by early 1991. On August 6th 1991, Tim Berners-Lee's post on the public alt.hypertext newsgroup is now considered as the official start of the World Wide Web as a public project. The HTTP protocol used in those early phases was very simple, later dubbed HTTP/0.9, and sometimes as the one-line protocol. The initial version of HTTP had no version number; it has been later called 0.9 to differentiate it from the later versions. HTTP/0.9 is extremely simple: requests consist of a single line and start with the only possible method {{HTTPMethod("GET")}} followed by the path to the resource (not the URL as both the protocol, server, and port are unnecessary once connected to the server). The response is extremely simple too: it only consisted of the file itself. Unlike subsequent evolutions, there were no HTTP headers, meaning that only HTML files could be transmitted, but no other type of documents. There were no status or error codes: in case of a problem, a specific HTML file was sent back with the description of the problem contained in it, for human consumption. HTTP/0.9 was very limited and both browsers and servers quickly extended it to be more versatile: At this point, a typical request and response looked like this: Followed by a second connection and request to fetch the image (followed by a response to that request): These novelties have not been introduced as concerted effort, but as a try-and-see approach over the 1991-1995 period: a server and a browser added one feature and it saw if it got traction. A lot of interoperability problems were common. In November 1996, in order to solve these annoyances, an informational document describing the common practices has been published, {{RFC(1945)}}. This is the definition of HTTP/1.0 and it is notable that, in the narrow sense of the term, it isn't an official standard. In parallel to the somewhat chaotic use of the diverse implementations of HTTP/1.0, and since 1995, well before the publication of HTTP/1.0 document the next year, proper standardization was in progress. The first standardized version of HTTP, HTTP/1.1 was published in early 1997, only a few months after HTTP/1.0. HTTP/1.1 clarified ambiguities and introduced numerous improvements: A typical flow of requests, all through one single connection is now looking like this: HTTP/1.1 was first published as {{rfc(2068)}} in January 1997. Thanks to its extensibility – creating new headers or methods is easy – and even if the HTTP/1.1 protocol was refined over two revisions, {{RFC("2616")}} published in June 1999 and the series of {{RFC("7230")}}-{{RFC("7235")}} published in June 2014 in prevision of the release of HTTP/2, this protocol has been extremely stable over more than 15 years. The largest change that happened to HTTP was done as early as end of 1994. Instead of sending HTTP over a basic TCP/IP stack, Netscape Communications created an additional encrypted transmission layer on top of it: SSL. SSL 1.0 was never released outside the company, but SSL 2.0 and its successor SSL 3.0 allowed for the creation of e-commerce Web sites by encrypting and guaranteeing the authenticity of the messages exchanged between the server and client. SSL was put on the standards track and eventually became TLS, with versions 1.0, 1.1, 1.2, and 1.3 appearing successfully to close vulnerabilities. During the same time, the need for an encrypted transport layer raised: the Web left the relative trustiness of a mostly academic network, to a jungle where advertisers, random individuals or criminals compete to get as much private information about people, try to impersonate them or even to replace data transmitted by altered ones. As the applications built over HTTP became more and more powerful, having access to more and more private information like address books, e-mail, or the geographic position of the user, the need to have TLS became ubiquitous even outside the e-commerce use case. The original vision of Tim Berners-Lee for the Web wasn't a read-only medium. He envisioned a Web where people can add and move documents remotely, a kind of distributed file system. Around 1996, HTTP has been extended to allow authoring, and a standard called WebDAV was created. It has been further extended for specific applications like CardDAV to handle address book entries and CalDAV to deal with calendars. But all these *DAV extensions had a flaw: they had to be implemented by the servers to be used, which was quite complex. Their use on Web realms stayed confidential. In 2000, a new pattern for using HTTP was designed: {{glossary("REST", "representational state transfer")}} (or REST). The actions induced by the API were no more conveyed by new HTTP methods, but only by accessing specific URIs with basic HTTP/1.1 methods. This allowed any Web application to provide an API to allow retrieval and modification of its data without having to update the browsers or the servers: all what is needed was embedded in the files served by the Web sites through standard HTTP/1.1. The drawback of the REST model resides in the fact that each website defines its own non-standard RESTful API and has total control on it; unlike the *DAV extensions where clients and servers are interoperable. RESTful APIs became very common in the 2010s. Since 2005, the set of APIs available to Web pages greatly increased and several of these APIs created extensions, mostly new specific HTTP headers, to the HTTP protocol for specific purposes: HTTP is independent of the security model of the Web, the same-origin policy. In fact, the current Web security model has been developed after the creation of HTTP! Over the years, it has proved useful to be able to be more lenient, by allowing under certain constraints to lift some of the restriction of this policy. How much and when such restrictions are lifted is transmitted by the server to the client using a new bunch of HTTP headers. These are defined in specifications like Cross-Origin Resource Sharing (CORS) or the Content Security Policy (CSP). In addition to these large extensions, numerous other headers have been added, sometimes experimentally only. Notable headers are Do Not Track ({{HTTPHeader("DNT")}}) header to control privacy, {{HTTPHeader("X-Frame-Options")}}, or {{HTTPHeader('Upgrade-Insecure-Requests')}} but many more exist. Over the years, Web pages have become much more complex, even becoming applications in their own right. The amount of visual media displayed, the volume and size of scripts adding interactivity, has also increased: much more data is transmitted over significantly more HTTP requests. HTTP/1.1 connections need requests sent in the correct order. Theoretically, several parallel connections could be used (typically between 5 and 8), bringing considerable overhead and complexity. For example, HTTP pipelining has emerged as a resource burden in Web development. In the first half of the 2010s, Google demonstrated an alternative way of exchanging data between client and server, by implementing an experimental protocol SPDY. This amassed interest from developers working on both browsers and servers. Defining an increase in responsiveness, and solving the problem of duplication of data transmitted, SPDY served as the foundations of the HTTP/2 protocol. The HTTP/2 protocol has several prime differences from the HTTP/1.1 version: Officially standardized, in May 2015, HTTP/2 has had much success. By July 2016, 8.7% of all Web sites were already using it (see these stats), representing more than 68% of all requests (see these statistics). High-traffic Web sites showed the most rapid adoption, saving considerably on data transfer overheads and subsequent budgets. This rapid adoption rate was likely as HTTP/2 does not require adaptation of Web sites and applications: using HTTP/1.1 or HTTP/2 is transparent for them. Having an up-to-date server communicating with a recent browser is enough to enable its use: only a limited set of groups were needed to trigger adoption, and as legacy browser and server versions are renewed, usage has naturally increased, without further Web developer efforts. HTTP didn't stop evolving upon the release of HTTP/2. Like with HTTP/1.x previously, HTTP's extensibility is still being used to add new features. Notably, we can cite new extensions of the HTTP protocol appearing in 2016: This evolution of HTTP proves its extensibility and simplicity, liberating creation of many applications and compelling the adoption of the protocol. The environment in which HTTP is used today is quite different from that seen in the early 1990s. HTTP's original design proved to be a masterpiece, allowing the Web to evolve over a quarter of a century, without the need of a mutiny. By healing flaws, yet retaining the flexibility and extensibility which made HTTP such a success, the adoption of HTTP/2 hints at a bright future for the protocol. {{Draft}}{{SeeCompatTable}} The next major version of HTTP, HTTP/3, will use {{Glossary("QUIC")}} instead {{Glossary("TCP")}}/{{Glossary("TLS")}} for the transport layer portion. See {{bug(1158011)}} for implementation status in Firefox. The target of an HTTP request is called a "resource", whose nature isn't defined further; it can be a document, a photo, or anything else. Each resource is identified by a Uniform Resource Identifier ({{Glossary("URI")}}) used throughout HTTP for identifying resources. The most common form of URI is the Uniform Resource Locator ({{Glossary("URL")}}), which is known as the web address. Any of those URLs can be typed into your browser's address bar to tell it to load the associated page (resource). A URL is composed of different parts, some mandatory and others are optional. A more complex example might look like this: A Uniform Resource Name (URN) is a URI that identifies a resource by name in a particular namespace. The two URNs correspond to When using URLs in {{Glossary("HTML")}} content, you should generally only use a few of these URL schemes. When referring to subresources — that is, files that are being loaded as part of a larger document — you should only use the HTTP and HTTPS schemes. Increasingly, browsers are removing support for using FTP to load subresources, for security reasons. FTP is still acceptable at the top level (such as typed directly into the browser's URL bar, or the target of a link), although some browsers may delegate loading FTP content to another application. HTTP is an extensible protocol that relies on concepts like resources and Uniform Resource Identifiers (URIs), simple message structure, and client-server communication flow. On top of these basic concepts, numerous extensions have been developed over the years that add updated functionality and semantics with new HTTP methods or headers. Here is a list of MIME types, associated by type of documents, ordered by their common extensions. Two primary MIME types are important for the role of default types: IANA is the official registry of MIME media types and maintains a list of all the official MIME types. This table lists some important MIME types for the Web:
- A media type (also known as a
- Multipurpose Internet Mail Extensions or MIME type) is a standard
- that indicates the nature and format of a document, file, or assortment of
- bytes. It is defined and standardized in IETF's {{RFC(6838)}}.
- The Internet Assigned Numbers Authority (IANA) is
- responsible for all official MIME types, and you can find the most up-to-date and
- complete list at their Media Types
- page.
- Warning: Browsers use the MIME type,
- not the file extension,
- to determine how to process a URL,
- so it's important
- that web servers send the correct MIME type in the response's {{HTTPHeader("Content-Type")}} header.
- If this is not correctly configured,
- browsers are likely to misinterpret the contents of files,
- sites will not work correctly,
- and downloaded files may be mishandled.
- The simplest MIME type consists of a type and a subtype; these
- are each strings which, when concatenated with a slash ( The type represents the general category into which the
- data type falls, such as Each type has its own set of possible subtypes, and a MIME type always has both a type
- and a subtype, never just one or the other. An optional parameter can be added to provide additional details: For example, for any MIME type whose main type is MIME types are case-insensitive but are traditionally written in lowercase, with the
- exception of parameter values, whose case may or may not have specific meaning. There are two classes of type: discrete and
- multipart. Discrete types are types which represent a single file or
- medium, such as a single text or music file, or a single video. A multipart type is one
- which represents a document that's comprised of multiple component parts, each of which
- may have its own individual MIME type; or, a multipart type may encapsulate multiple
- files being sent together in one transaction. For example, multipart MIME types are used
- when attaching multiple files to an email. The discrete types currently registered with the IANA are: For text documents without a specific subtype, Multipart types indicate a category of document broken into
- pieces, often with different MIME types; they can also be used — especially in email
- scenarios — to represent multiple, separate files which are all part of the same
- transaction. They represent a composite document. With the exception of There are two multipart types: This is the default for binary files. As it means unknown binary file,
- browsers usually don't execute it, or even ask if it should be executed. They treat it
- as if the {{HTTPHeader("Content-Disposition")}} header was set to
- This is the default for textual files. Even if it really means "unknown textual file,"
- browsers assume they can display it. Note: CSS files used to style a Web page must be sent with
- All HTML content should be served with this type. Alternative MIME types for XHTML
- (like Note: Use Per the HTML specification, JavaScript files should always be served using the MIME
- type For historical reasons, the MIME Sniffing
- Standard (the definition of how browsers should interpret media types and figure
- out what to do with content that doesn't have a valid one) allows JavaScript to be
- served using any MIME type that essentially matches any of the following: Note: Even though any given {{Glossary("user agent")}} may support
- any or all of these, you should only use Some content you find may have a Files whose MIME type is {{page("en-US/docs/Web/Media/Formats/Image_types", "table-of-image-file-types")}} As is the case for images, HTML doesn't mandate that web browsers support any specific
- file and codec types for the {{HTMLElement("audio")}} and {{HTMLElement("video")}}
- elements, so it's important to consider your target audience and the range of browsers
- (and versions of those browsers) they may be using when choosing the file type and
- codecs to use for media. Our media container formats
- guide provides a list of the file types that are commonly supported by web
- browsers, including information about what their special use cases may be, any drawbacks
- they have, and compatibility information, along with other details. The audio codec and video codec guides list the
- various codecs that web browsers often support, providing compatibility details along
- with technical information such as how many audio channels they support, what sort of
- compression is used, and what bit rates and so forth they're useful at. The codecs used by WebRTC guide
- expands upon this by specifically covering the codecs supported by the major web
- browsers, so you can choose the codecs that best cover the range of browsers you wish to
- support. As for MIME types of audio or video files, they typically specify the container format
- (file type). The optional codecs parameter can be
- added to the MIME type to further specify which codecs to use and what options were used
- to encode the media, such as codec profile, level, or other such information. The most commonly used MIME types used for web content are listed below. This isn't a
- complete list of all the types that may be available, however. See the media container formats guide for
- that. The As a multipart document format, it consists of different parts, delimited by a boundary
- (a string starting with a double dash The following will send this message: The When the {{HTTPStatus("206")}} Most web servers send unrecognized resources as the
- Some common incorrect server configurations: RAR-compressed files. In this case, the ideal would be the true type of the
- original files; this is often impossible as .RAR files can hold several resources of
- different types. In this case, configure the server to send
- Audio and video. Only resources with the correct MIME Type will be played in
- {{HTMLElement("video")}} or {{HTMLElement("audio")}} elements. Be sure to specify
- the correct media type for audio and
- video. Proprietary file types. Avoid using In the absence of a MIME type, or in certain cases where browsers believe they are
- incorrect, browsers may perform MIME sniffing — guessing the correct MIME type
- by looking at the bytes of the resource. Each browser performs MIME sniffing differently and under different circumstances. (For
- example, Safari will look at the file extension in the URL if the sent MIME type is
- unsuitable.) There are security concerns as some MIME types represent executable
- content. Servers can prevent MIME sniffing by sending the
- {{HTTPHeader("X-Content-Type-Options")}} header. MIME types are not the only way to convey document type information:Invention of the World Wide Web
-
-
-
-
-HTTP/0.9 – The one-line protocol
-
-GET /mypage.html
-
-<HTML>
-A very simple HTML page
-</HTML>
-
-HTTP/1.0 – Building extensibility
-
-
-
-
-HTTP/1.0
is appended to the GET
line)GET /mypage.html HTTP/1.0
-User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
-
-200 OK
-Date: Tue, 15 Nov 1994 08:12:31 GMT
-Server: CERN/3.0 libwww/2.17
-Content-Type: text/html
-<HTML>
-A page with an image
- <IMG SRC="/myimage.gif">
-</HTML>
-
-GET /myimage.gif HTTP/1.0
-User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
-
-200 OK
-Date: Tue, 15 Nov 1994 08:12:32 GMT
-Server: CERN/3.0 libwww/2.17
-Content-Type: text/gif
-(image content)
-
-HTTP/1.1 – The standardized protocol
-
-
-
-
-GET /en-US/docs/Glossary/Simple_header HTTP/1.1
-Host: developer.mozilla.org
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate, br
-Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
-
-200 OK
-Connection: Keep-Alive
-Content-Encoding: gzip
-Content-Type: text/html; charset=utf-8
-Date: Wed, 20 Jul 2016 10:55:30 GMT
-Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
-Keep-Alive: timeout=5, max=1000
-Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
-Server: Apache
-Transfer-Encoding: chunked
-Vary: Cookie, Accept-Encoding
-
-(content)
-
-GET /static/img/header-background.png HTTP/1.1
-Host: developer.mozilla.org
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
-Accept: */*
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate, br
-Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
-
-200 OK
-Age: 9578461
-Cache-Control: public, max-age=315360000
-Connection: keep-alive
-Content-Length: 3077
-Content-Type: image/png
-Date: Thu, 31 Mar 2016 13:34:46 GMT
-Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
-Server: Apache
-
-(image content of 3077 bytes)
-
-More than 15 years of extensions
-
-Using HTTP for secure transmissions
-
-Using HTTP for complex applications
-
-
-
-
-Relaxing the security-model of the Web
-
-HTTP/2 – A protocol for greater performance
-
-
-
-
-Post-HTTP/2 evolution
-
-
-
-
-HTTP/3 - HTTP over QUIC
-
-
+
+```
+
+Followed by a second connection and request to fetch the image (followed by a response to that request):
+
+```
+ GET /myimage.gif HTTP/1.0
+ User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
+
+ 200 OK
+ Date: Tue, 15 Nov 1994 08:12:32 GMT
+ Server: CERN/3.0 libwww/2.17
+ Content-Type: text/gif
+ (image content)
+```
+
+These novelties have not been introduced as concerted effort, but as a try-and-see approach over the 1991-1995 period: a server and a browser added one feature and it saw if it got traction. A lot of interoperability problems were common. In November 1996, in order to solve these annoyances, an informational document describing the common practices has been published, {{RFC(1945)}}. This is the definition of HTTP/1.0 and it is notable that, in the narrow sense of the term, it isn't an official standard.
+
+## HTTP/1.1 – The standardized protocol
+
+In parallel to the somewhat chaotic use of the diverse implementations of HTTP/1.0, and since 1995, well before the publication of HTTP/1.0 document the next year, proper standardization was in progress. The first standardized version of HTTP, HTTP/1.1 was published in early 1997, only a few months after HTTP/1.0.
+
+HTTP/1.1 clarified ambiguities and introduced numerous improvements:
+
+- A connection can be reused, saving the time to reopen it numerous times to display the resources embedded into the single original document retrieved.
+- Pipelining has been added, allowing to send a second request before the answer for the first one is fully transmitted, lowering the latency of the communication.
+- Chunked responses are now also supported.
+- Additional cache control mechanisms have been introduced.
+- Content negotiation, including language, encoding, or type, has been introduced, and allows a client and a server to agree on the most adequate content to exchange.
+- Thanks to the {{HTTPHeader("Host")}} header, the ability to host different domains at the same IP address now allows server colocation.
+
+A typical flow of requests, all through one single connection is now looking like this:
+
+```
+GET /en-US/docs/Glossary/Simple_header HTTP/1.1
+Host: developer.mozilla.org
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+Accept-Language: en-US,en;q=0.5
+Accept-Encoding: gzip, deflate, br
+Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
+
+200 OK
+Connection: Keep-Alive
+Content-Encoding: gzip
+Content-Type: text/html; charset=utf-8
+Date: Wed, 20 Jul 2016 10:55:30 GMT
+Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
+Keep-Alive: timeout=5, max=1000
+Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
+Server: Apache
+Transfer-Encoding: chunked
+Vary: Cookie, Accept-Encoding
+
+(content)
+
+GET /static/img/header-background.png HTTP/1.1
+Host: developer.mozilla.org
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
+Accept: */*
+Accept-Language: en-US,en;q=0.5
+Accept-Encoding: gzip, deflate, br
+Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
+
+200 OK
+Age: 9578461
+Cache-Control: public, max-age=315360000
+Connection: keep-alive
+Content-Length: 3077
+Content-Type: image/png
+Date: Thu, 31 Mar 2016 13:34:46 GMT
+Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
+Server: Apache
+
+(image content of 3077 bytes)
+```
+
+HTTP/1.1 was first published as {{rfc(2068)}} in January 1997.
+
+## More than 15 years of extensions
+
+Thanks to its extensibility – creating new headers or methods is easy – and even if the HTTP/1.1 protocol was refined over two revisions, {{RFC("2616")}} published in June 1999 and the series of {{RFC("7230")}}-{{RFC("7235")}} published in June 2014 in prevision of the release of HTTP/2, this protocol has been extremely stable over more than 15 years.
+
+### Using HTTP for secure transmissions
+
+The largest change that happened to HTTP was done as early as end of 1994. Instead of sending HTTP over a basic TCP/IP stack, Netscape Communications created an additional encrypted transmission layer on top of it: SSL. SSL 1.0 was never released outside the company, but SSL 2.0 and its successor SSL 3.0 allowed for the creation of e-commerce Web sites by encrypting and guaranteeing the authenticity of the messages exchanged between the server and client. SSL was put on the standards track and eventually became TLS, with versions 1.0, 1.1, 1.2, and 1.3 appearing successfully to close vulnerabilities.
+
+During the same time, the need for an encrypted transport layer raised: the Web left the relative trustiness of a mostly academic network, to a jungle where advertisers, random individuals or criminals compete to get as much private information about people, try to impersonate them or even to replace data transmitted by altered ones. As the applications built over HTTP became more and more powerful, having access to more and more private information like address books, e-mail, or the geographic position of the user, the need to have TLS became ubiquitous even outside the e-commerce use case.
+
+### Using HTTP for complex applications
+
+The original vision of Tim Berners-Lee for the Web wasn't a read-only medium. He envisioned a Web where people can add and move documents remotely, a kind of distributed file system. Around 1996, HTTP has been extended to allow authoring, and a standard called WebDAV was created. It has been further extended for specific applications like CardDAV to handle address book entries and CalDAV to deal with calendars. But all these \*DAV extensions had a flaw: they had to be implemented by the servers to be used, which was quite complex. Their use on Web realms stayed confidential.
+
+In 2000, a new pattern for using HTTP was designed: {{glossary("REST", "representational state transfer")}} (or REST). The actions induced by the API were no more conveyed by new HTTP methods, but only by accessing specific URIs with basic HTTP/1.1 methods. This allowed any Web application to provide an API to allow retrieval and modification of its data without having to update the browsers or the servers: all what is needed was embedded in the files served by the Web sites through standard HTTP/1.1. The drawback of the REST model resides in the fact that each website defines its own non-standard RESTful API and has total control on it; unlike the \*DAV extensions where clients and servers are interoperable. RESTful APIs became very common in the 2010s.
+
+Since 2005, the set of APIs available to Web pages greatly increased and several of these APIs created extensions, mostly new specific HTTP headers, to the HTTP protocol for specific purposes:
+
+- [Server-sent events](/en-US/docs/Web/API/Server-sent_events), where the server can push occasional messages to the browser.
+- [WebSocket](/en-US/docs/Web/API/WebSockets_API), a new protocol that can be set up by upgrading an existing HTTP connection.
+
+### Relaxing the security-model of the Web
+
+HTTP is independent of the security model of the Web, the [same-origin policy](/en-US/docs/Web/Security/Same-origin_policy). In fact, the current Web security model has been developed after the creation of HTTP! Over the years, it has proved useful to be able to be more lenient, by allowing under certain constraints to lift some of the restriction of this policy. How much and when such restrictions are lifted is transmitted by the server to the client using a new bunch of HTTP headers. These are defined in specifications like [Cross-Origin Resource Sharing](/en-US/docs/Glossary/CORS) (CORS) or the [Content Security Policy](/en-US/docs/Web/HTTP/CSP) (CSP).
+
+In addition to these large extensions, numerous other headers have been added, sometimes experimentally only. Notable headers are Do Not Track ({{HTTPHeader("DNT")}}) header to control privacy, {{HTTPHeader("X-Frame-Options")}}, or {{HTTPHeader('Upgrade-Insecure-Requests')}} but many more exist.
+
+## HTTP/2 – A protocol for greater performance
+
+Over the years, Web pages have become much more complex, even becoming applications in their own right. The amount of visual media displayed, the volume and size of scripts adding interactivity, has also increased: much more data is transmitted over significantly more HTTP requests. HTTP/1.1 connections need requests sent in the correct order. Theoretically, several parallel connections could be used (typically between 5 and 8), bringing considerable overhead and complexity. For example, HTTP pipelining has emerged as a resource burden in Web development.
+
+In the first half of the 2010s, Google demonstrated an alternative way of exchanging data between client and server, by implementing an experimental protocol SPDY. This amassed interest from developers working on both browsers and servers. Defining an increase in responsiveness, and solving the problem of duplication of data transmitted, SPDY served as the foundations of the HTTP/2 protocol.
+
+The HTTP/2 protocol has several prime differences from the HTTP/1.1 version:
+
+- It is a binary protocol rather than text. It can no longer be read and created manually. Despite this hurdle, improved optimization techniques can now be implemented.
+- It is a multiplexed protocol. Parallel requests can be handled over the same connection, removing the order and blocking constraints of the HTTP/1.x protocol.
+- It compresses headers. As these are often similar among a set of requests, this removes duplication and overhead of data transmitted.
+- It allows a server to populate data in a client cache, in advance of it being required, through a mechanism called the server push.
+
+Officially standardized, in May 2015, HTTP/2 has had much success. By July 2016, 8.7% of all Web sites were already using it (see [these stats](https://w3techs.com/technologies/details/ce-http2/all/all)), representing more than 68% of all requests (see [these statistics](https://www.keycdn.com/blog/http2-statistics/)). High-traffic Web sites showed the most rapid adoption, saving considerably on data transfer overheads and subsequent budgets.
+
+This rapid adoption rate was likely as HTTP/2 does not require adaptation of Web sites and applications: using HTTP/1.1 or HTTP/2 is transparent for them. Having an up-to-date server communicating with a recent browser is enough to enable its use: only a limited set of groups were needed to trigger adoption, and as legacy browser and server versions are renewed, usage has naturally increased, without further Web developer efforts.
+
+## Post-HTTP/2 evolution
+
+HTTP didn't stop evolving upon the release of HTTP/2. Like with HTTP/1.x previously, HTTP's extensibility is still being used to add new features. Notably, we can cite new extensions of the HTTP protocol appearing in 2016:
+
+- Support of {{HTTPHeader("Alt-Svc")}} allows the dissociation of the identification and the location of a given resource, allowing for a smarter {{Glossary("CDN")}} caching mechanism.
+- The introduction of {{HTTPHeader("Client-Hints")}} allows the browser, or client, to proactively communicate information about its requirements, or hardware constraints, to the server.
+- The introduction of security-related prefixes in the {{HTTPHeader("Cookie")}} header, now helps guarantee a secure cookie has not been altered.
+
+This evolution of HTTP proves its extensibility and simplicity, liberating creation of many applications and compelling the adoption of the protocol. The environment in which HTTP is used today is quite different from that seen in the early 1990s. HTTP's original design proved to be a masterpiece, allowing the Web to evolve over a quarter of a century, without the need of a mutiny. By healing flaws, yet retaining the flexibility and extensibility which made HTTP such a success, the adoption of HTTP/2 hints at a bright future for the protocol.
+
+## HTTP/3 - HTTP over QUIC
+
+{{Draft}}{{SeeCompatTable}}
+
+The next major version of HTTP, HTTP/3, will use {{Glossary("QUIC")}} instead {{Glossary("TCP")}}/{{Glossary("TLS")}} for the transport layer portion.
+
+See {{bug(1158011)}} for implementation status in Firefox.
diff --git a/files/en-us/web/http/basics_of_http/identifying_resources_on_the_web/index.html b/files/en-us/web/http/basics_of_http/identifying_resources_on_the_web/index.html
deleted file mode 100644
index 3384afd42c6e010..000000000000000
--- a/files/en-us/web/http/basics_of_http/identifying_resources_on_the_web/index.html
+++ /dev/null
@@ -1,189 +0,0 @@
----
-title: Identifying resources on the Web
-slug: Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web
-tags:
- - Domain
- - HTTP
- - Path
- - Scheme
- - Syntax
- - URI
- - URL
- - URL Syntax
- - Web
- - fragment
- - port
- - query
- - resources
----
-
URLs and URNs
-
-URLs
-
-https://developer.mozilla.org
-https://developer.mozilla.org/en-US/docs/Learn/
-https://developer.mozilla.org/en-US/search?q=URL
-
-http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
-
-URNs
-
-urn:isbn:9780141036144
-urn:ietf:rfc:7230
-
-
-
-
-
-Syntax of Uniform Resource Identifiers (URIs)
-
-Scheme or protocol
-
-
-
-
-http://
is the protocol. It indicates which protocol the browser must use. Usually it is the HTTP protocol or its secured version, HTTPS. The Web requires one of these two, but browsers also know how to handle other protocols such as mailto:
(to open a mail client) or ftp:
to handle file transfer, so don't be surprised if you see such protocols. Common schemes are:
-
-
-
-
-
-
-
- Scheme
- Description
-
-
- data
- Data URIs
-
-
- file
- Host-specific file names
-
-
- ftp
- {{Glossary("FTP","File Transfer Protocol")}}
-
-
- http/https
- Hyper text transfer protocol (Secure)
-
-
- javascript
- URL-embedded JavaScript code
-
-
- mailto
- Electronic mail address
-
-
- ssh
- Secure shell
-
-
- tel
- telephone
-
-
- urn
- Uniform Resource Names
-
-
- view-source
- Source code of the resource
-
-
-
-ws/wss
- WebSocket connections (Secure)
- Authority
-
-
-
-
-www.example.com
is the domain name or authority that governs the namespace. It indicates which Web server is being requested. Alternatively, it is possible to directly use an {{Glossary("IP address")}}, but because it is less convenient, it is not often used on the Web.Port
-
-
-
-
-:80
is the port in this instance. It indicates the technical "gate" used to access the resources on the web server. It is usually omitted if the web server uses the standard ports of the HTTP protocol (80 for HTTP and 443 for HTTPS) to grant access to its resources. Otherwise it is mandatory.Path
-
-
-
-
-/path/to/myfile.html
is the path to the resource on the Web server. In the early days of the Web, a path like this represented a physical file location on the Web server. Nowadays, it is mostly an abstraction handled by Web servers without any physical reality.Query
-
-
-
-
-?key1=value1&key2=value2
are extra parameters provided to the Web server. Those parameters are a list of key/value pairs separated with the &
symbol. The Web server can use those parameters to do extra stuff before returning the resource to the user. Each Web server has its own rules regarding parameters, and the only reliable way to know how a specific Web server is handling parameters is by asking the Web server owner.Fragment
-
-
-
-
-#SomewhereInTheDocument
is an anchor to another part of the resource itself. An anchor represents a sort of "bookmark" inside the resource, giving the browser the directions to show the content located at that "bookmarked" spot. On an HTML document, for example, the browser will scroll to the point where the anchor is defined; on a video or audio document, the browser will try to go to the time the anchor represents. It is worth noting that the part after the #, also known as fragment identifier, is never sent to the server with the request.Usage notes
-
-Examples
-
-https://developer.mozilla.org/en-US/docs/Learn
-tel:+1-816-555-1212
-git@github.com:mdn/browser-compat-data.git
-ftp://example.org/resource.txt
-urn:isbn:9780141036144
-mailto:help@supercyberhelpdesk.info
-
-
-Specifications
-
-
-
-
-
-
-
- Specification
- Title
-
-
-
-{{RFC("7230", "Uniform Resource Identifiers", "2.7")}}
- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
- See also
-
-
diff --git a/files/en-us/web/http/basics_of_http/identifying_resources_on_the_web/index.md b/files/en-us/web/http/basics_of_http/identifying_resources_on_the_web/index.md
new file mode 100644
index 000000000000000..1ee1ed9904f0e3c
--- /dev/null
+++ b/files/en-us/web/http/basics_of_http/identifying_resources_on_the_web/index.md
@@ -0,0 +1,129 @@
+---
+title: Identifying resources on the Web
+slug: Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web
+tags:
+ - Domain
+ - HTTP
+ - Path
+ - Scheme
+ - Syntax
+ - URI
+ - URL
+ - URL Syntax
+ - Web
+ - fragment
+ - port
+ - query
+ - resources
+---
+{{HTTPSidebar}}
+
+The target of an HTTP request is called a "resource", whose nature isn't defined further; it can be a document, a photo, or anything else. Each resource is identified by a Uniform Resource Identifier ({{Glossary("URI")}}) used throughout HTTP for identifying resources.
+
+## URLs and URNs
+
+### URLs
+
+The most common form of URI is the Uniform Resource Locator ({{Glossary("URL")}}), which is known as the _web address_.
+
+```
+https://developer.mozilla.org
+https://developer.mozilla.org/en-US/docs/Learn/
+https://developer.mozilla.org/en-US/search?q=URL
+```
+
+Any of those URLs can be typed into your browser's address bar to tell it to load the associated page (resource).
+
+A URL is composed of different parts, some mandatory and others are optional. A more complex example might look like this:
+
+```
+http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
+```
+
+### URNs
+
+A Uniform Resource Name (URN) is a URI that identifies a resource by name in a particular namespace.
+
+```
+urn:isbn:9780141036144
+urn:ietf:rfc:7230
+```
+
+The two URNs correspond to
+
+- the book Nineteen Eighty-Four by George Orwell,
+- the IETF specification 7230, Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing.
+
+## Syntax of Uniform Resource Identifiers (URIs)
+
+### Scheme or protocol
+
+- 
+ - : `http://` is the protocol. It indicates which protocol the browser must use. Usually it is the HTTP protocol or its secured version, HTTPS. The Web requires one of these two, but browsers also know how to handle other protocols such as `mailto:` (to open a mail client) or `ftp:` to handle file transfer, so don't be surprised if you see such protocols. Common schemes are:
+
+| Scheme | Description |
+| ----------- | -------------------------------------------------------------------- |
+| data | [Data URIs](/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) |
+| file | Host-specific file names |
+| ftp | {{Glossary("FTP","File Transfer Protocol")}} |
+| http/https | [Hyper text transfer protocol (Secure)](/en-US/docs/Glossary/HTTP) |
+| javascript | URL-embedded JavaScript code |
+| mailto | Electronic mail address |
+| ssh | Secure shell |
+| tel | telephone |
+| urn | Uniform Resource Names |
+| view-source | Source code of the resource |
+| ws/wss | [WebSocket connections (Secure)](/en-US/docs/Web/API/WebSockets_API) |
+
+### Authority
+
+- 
+ - : `www.example.com` is the domain name or authority that governs the namespace. It indicates which Web server is being requested. Alternatively, it is possible to directly use an {{Glossary("IP address")}}, but because it is less convenient, it is not often used on the Web.
+
+### Port
+
+- 
+ - : `:80` is the port in this instance. It indicates the technical "gate" used to access the resources on the web server. It is usually omitted if the web server uses the standard ports of the HTTP protocol (80 for HTTP and 443 for HTTPS) to grant access to its resources. Otherwise it is mandatory.
+
+### Path
+
+- 
+ - : `/path/to/myfile.html` is the path to the resource on the Web server. In the early days of the Web, a path like this represented a physical file location on the Web server. Nowadays, it is mostly an abstraction handled by Web servers without any physical reality.
+
+### Query
+
+- 
+ - : `?key1=value1&key2=value2` are extra parameters provided to the Web server. Those parameters are a list of key/value pairs separated with the `&` symbol. The Web server can use those parameters to do extra stuff before returning the resource to the user. Each Web server has its own rules regarding parameters, and the only reliable way to know how a specific Web server is handling parameters is by asking the Web server owner.
+
+### Fragment
+
+- 
+ - : `#SomewhereInTheDocument` is an anchor to another part of the resource itself. An anchor represents a sort of "bookmark" inside the resource, giving the browser the directions to show the content located at that "bookmarked" spot. On an HTML document, for example, the browser will scroll to the point where the anchor is defined; on a video or audio document, the browser will try to go to the time the anchor represents. It is worth noting that the part after the #, also known as fragment identifier, is never sent to the server with the request.
+
+## Usage notes
+
+When using URLs in {{Glossary("HTML")}} content, you should generally only use a few of these URL schemes. When referring to subresources — that is, files that are being loaded as part of a larger document — you should only use the HTTP and HTTPS schemes. Increasingly, browsers are removing support for using FTP to load subresources, for security reasons.
+
+FTP is still acceptable at the top level (such as typed directly into the browser's URL bar, or the target of a link), although some browsers may delegate loading FTP content to another application.
+
+## Examples
+
+```
+https://developer.mozilla.org/en-US/docs/Learn
+tel:+1-816-555-1212
+git@github.com:mdn/browser-compat-data.git
+ftp://example.org/resource.txt
+urn:isbn:9780141036144
+mailto:help@supercyberhelpdesk.info
+```
+
+## Specifications
+
+| Specification | Title |
+| ------------------------------------------------------------------------ | ------------------------------------------------------------------ |
+| {{RFC("7230", "Uniform Resource Identifiers", "2.7")}} | Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing |
+
+## See also
+
+- [What is a URL?](/en-US/docs/Learn/Common_questions/What_is_a_URL)
+- [IANA list of URI schemes](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml)
diff --git a/files/en-us/web/http/basics_of_http/index.html b/files/en-us/web/http/basics_of_http/index.html
deleted file mode 100644
index 5df8ff46f459c12..000000000000000
--- a/files/en-us/web/http/basics_of_http/index.html
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: Basics of HTTP
-slug: Web/HTTP/Basics_of_HTTP
-tags:
- - Guide
- - HTTP
- - Overview
----
-Articles
-
-
-
diff --git a/files/en-us/web/http/basics_of_http/index.md b/files/en-us/web/http/basics_of_http/index.md
new file mode 100644
index 000000000000000..1ce0f80f264603f
--- /dev/null
+++ b/files/en-us/web/http/basics_of_http/index.md
@@ -0,0 +1,42 @@
+---
+title: Basics of HTTP
+slug: Web/HTTP/Basics_of_HTTP
+tags:
+ - Guide
+ - HTTP
+ - Overview
+---
+{{HTTPSidebar}}
+
+HTTP is an extensible protocol that relies on concepts like resources and Uniform Resource Identifiers (URIs), simple message structure, and client-server communication flow. On top of these basic concepts, numerous extensions have been developed over the years that add updated functionality and semantics with new HTTP methods or headers.
+
+## Articles
+
+- [Overview of HTTP](/en-US/docs/Web/HTTP/Overview)
+ - : Describes what HTTP is and its role in web architecture, including its position in the protocol stack.
+- [Evolution of HTTP](/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP)
+ - : HTTP was created in the early 1990s and has been extended several times. This article goes through its history and describes HTTP/0.9, HTTP/1.0, HTTP/1.1, and the modern HTTP/2, as well as novelties introduced over the years.
+- [Resources and URIs](/en-US/docs/Web/HTTP/Resources_and_URIs)
+ - : A brief introduction to the concept of resources, identifiers, and locations on the web.
+- [Identifying resources on the Web](/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web)
+ - : Describes how web resources are referenced and how to locate them.
+- [Data URIs](/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs)
+ - : A specific kind of URI that directly embeds the resource it represents. Data URIs are very convenient, but have some caveats.
+- [Resource URLs](/en-US/docs/Web/HTTP/Basics_of_HTTP/Resource_URLs) {{Non-standard_Inline}}
+ - : Resource URLs, those prefixed with the `resource` scheme are used by Firefox and Firefox browser extensions to load resources internally, but is also available to some sites the browser connects to as well.
+- [MIME types](/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)
+ - : Since HTTP/1.0, different types of content can be transmitted. This article explains how this is accomplished using the {{HTTPHeader("Content-Type")}} header and the MIME standard.
+- [Choosing between www and non-www URLs](/en-US/docs/Web/HTTP/Basics_of_HTTP/Choosing_between_www_and_non-www_URLs)
+ - : This article provides guidance on how to choose whether to use a www-prefixed domain or not, along with the consequences of that choice.
+- [Flow of an HTTP session](/en-US/docs/Web/HTTP/Session)
+ - : This article describes a typical HTTP session; i.e. what happens when you follow a link or load an image into a web page.
+- [HTTP Messages](/en-US/docs/Web/HTTP/Messages)
+ - : HTTP Messages transmitted during requests or responses have a very clear structure. This introductory article describes this structure, its purpose, and its possibilities.
+- [Frame and message structure in HTTP/2](/en-US/docs/Web/HTTP/Frame_and_message_structure_in_HTTP_2)
+ - : HTTP/2 encapsulates and represents HTTP/1.x messages in a binary frame. This article explains the frame structure, its purpose, and the way it's encoded.
+- [Connection management in HTTP/1.x](/en-US/docs/Web/HTTP/Connection_management_in_HTTP_1.x)
+ - : HTTP/1.1 was the first version of HTTP to support persistent connection and pipelining. This article explains both concepts.
+- [Connection management in HTTP/2](/en-US/docs/Web/HTTP/Connection_management_in_HTTP_2)
+ - : HTTP/2 completely revisited how connections are created and maintained. This article explains how HTTP frames allow multiplexing and solve the 'head-of-line' blocking problem of former HTTP versions.
+- [Content Negotiation](/en-US/docs/Web/HTTP/Content_negotiation)
+ - : HTTP introduces a set of headers, starting with [`Accept`](/en-US/docs/Web/HTTP/Headers/Accept) as a way for a browser to announce the format, language, or encoding it prefers. This article explains how this advertisement happens, how the server is expected to react, and how it chooses the most adequate response.
diff --git a/files/en-us/web/http/basics_of_http/mime_types/common_types/index.html b/files/en-us/web/http/basics_of_http/mime_types/common_types/index.html
deleted file mode 100644
index 7d0a1c41d7de71e..000000000000000
--- a/files/en-us/web/http/basics_of_http/mime_types/common_types/index.html
+++ /dev/null
@@ -1,409 +0,0 @@
----
-title: Common MIME types
-slug: Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
-tags:
- - Audio
- - File Types
- - Files
- - HTTP
- - MIME
- - MIME Types
- - PHP
- - Reference
- - Text
- - Types
- - Video
----
-resource
scheme are used by Firefox and Firefox browser extensions to load resources internally, but is also available to some sites the browser connects to as well.Accept
as a way for a browser to announce the format, language, or encoding it prefers. This article explains how this advertisement happens, how the server is expected to react, and how it chooses the most adequate response.
-
-
-text/plain
is the default value for textual files. A textual file should be human-readable and must not contain binary data.application/octet-stream
is the default value for all other cases. An unknown file type should use this type. Browsers pay a particular care when manipulating these files, attempting to safeguard the user to prevent dangerous behaviors.
-
-
diff --git a/files/en-us/web/http/basics_of_http/mime_types/common_types/index.md b/files/en-us/web/http/basics_of_http/mime_types/common_types/index.md
new file mode 100644
index 000000000000000..db93902d1a5445d
--- /dev/null
+++ b/files/en-us/web/http/basics_of_http/mime_types/common_types/index.md
@@ -0,0 +1,101 @@
+---
+title: Common MIME types
+slug: Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
+tags:
+ - Audio
+ - File Types
+ - Files
+ - HTTP
+ - MIME
+ - MIME Types
+ - PHP
+ - Reference
+ - Text
+ - Types
+ - Video
+---
+{{HTTPSidebar}}
+
+Here is a list of MIME types, associated by type of documents, ordered by their common extensions.
+
+Two primary MIME types are important for the role of default types:
+
+- `text/plain` is the default value for textual files. A textual file should be human-readable and must not contain binary data.
+- `application/octet-stream` is the default value for all other cases. An unknown file type should use this type. Browsers pay a particular care when manipulating these files, attempting to safeguard the user to prevent dangerous behaviors.
+
+IANA is the official registry of MIME media types and maintains a [list of all the official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml). This table lists some important MIME types for the Web:
+
+| Extension | Kind of document | MIME Type |
+| -------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `.aac` | AAC audio | `audio/aac` |
+| `.abw` | [AbiWord](https://en.wikipedia.org/wiki/AbiWord) document | `application/x-abiword` |
+| `.arc` | Archive document (multiple files embedded) | `application/x-freearc` |
+| `.avi` | AVI: Audio Video Interleave | `video/x-msvideo` |
+| `.azw` | Amazon Kindle eBook format | `application/vnd.amazon.ebook` |
+| `.bin` | Any kind of binary data | `application/octet-stream` |
+| `.bmp` | Windows OS/2 Bitmap Graphics | `image/bmp` |
+| `.bz` | BZip archive | `application/x-bzip` |
+| `.bz2` | BZip2 archive | `application/x-bzip2` |
+| `.cda` | CD audio | `application/x-cdf` |
+| `.csh` | C-Shell script | `application/x-csh` |
+| `.css` | Cascading Style Sheets (CSS) | `text/css` |
+| `.csv` | Comma-separated values (CSV) | `text/csv` |
+| `.doc` | Microsoft Word | `application/msword` |
+| `.docx` | Microsoft Word (OpenXML) | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
+| `.eot` | MS Embedded OpenType fonts | `application/vnd.ms-fontobject` |
+| `.epub` | Electronic publication (EPUB) | `application/epub+zip` |
+| `.gz` | GZip Compressed Archive | `application/gzip` |
+| `.gif` | Graphics Interchange Format (GIF) | `image/gif` |
+| `.htm .html` | HyperText Markup Language (HTML) | `text/html` |
+| `.ico` | Icon format | `image/vnd.microsoft.icon` |
+| `.ics` | iCalendar format | `text/calendar` |
+| `.jar` | Java Archive (JAR) | `application/java-archive` |
+| `.jpeg` `.jpg` | JPEG images | `image/jpeg` |
+| `.js` | JavaScript | `text/javascript` (Specifications: [HTML](https://html.spec.whatwg.org/multipage/#scriptingLanguages) and its [reasoning](https://html.spec.whatwg.org/multipage/#dependencies:willful-violation), and [IETF](https://datatracker.ietf.org/doc/draft-ietf-dispatch-javascript-mjs/)) |
+| `.json` | JSON format | `application/json` |
+| `.jsonld` | JSON-LD format | `application/ld+json` |
+| `.mid` `.midi` | Musical Instrument Digital Interface (MIDI) | `audio/midi` `audio/x-midi` |
+| `.mjs` | JavaScript module | `text/javascript` |
+| `.mp3` | MP3 audio | `audio/mpeg` |
+| `.mp4` | MP4 audio | `video/mp4` |
+| `.mpeg` | MPEG Video | `video/mpeg` |
+| `.mpkg` | Apple Installer Package | `application/vnd.apple.installer+xml` |
+| `.odp` | OpenDocument presentation document | `application/vnd.oasis.opendocument.presentation` |
+| `.ods` | OpenDocument spreadsheet document | `application/vnd.oasis.opendocument.spreadsheet` |
+| `.odt` | OpenDocument text document | `application/vnd.oasis.opendocument.text` |
+| `.oga` | OGG audio | `audio/ogg` |
+| `.ogv` | OGG video | `video/ogg` |
+| `.ogx` | OGG | `application/ogg` |
+| `.opus` | Opus audio | `audio/opus` |
+| `.otf` | OpenType font | `font/otf` |
+| `.png` | Portable Network Graphics | `image/png` |
+| `.pdf` | Adobe [Portable Document Format](https://acrobat.adobe.com/us/en/why-adobe/about-adobe-pdf.html) (PDF) | `application/pdf` |
+| `.php` | Hypertext Preprocessor (**Personal Home Page**) | `application/x-httpd-php` |
+| `.ppt` | Microsoft PowerPoint | `application/vnd.ms-powerpoint` |
+| `.pptx` | Microsoft PowerPoint (OpenXML) | `application/vnd.openxmlformats-officedocument.presentationml.presentation` |
+| `.rar` | RAR archive | `application/vnd.rar` |
+| `.rtf` | Rich Text Format (RTF) | `application/rtf` |
+| `.sh` | Bourne shell script | `application/x-sh` |
+| `.svg` | Scalable Vector Graphics (SVG) | `image/svg+xml` |
+| `.swf` | [Small web format](https://en.wikipedia.org/wiki/SWF) (SWF) or Adobe Flash document | `application/x-shockwave-flash` |
+| `.tar` | Tape Archive (TAR) | `application/x-tar` |
+| `.tif .tiff` | Tagged Image File Format (TIFF) | `image/tiff` |
+| `.ts` | MPEG transport stream | `video/mp2t` |
+| `.ttf` | TrueType Font | `font/ttf` |
+| `.txt` | Text, (generally ASCII or ISO 8859-_n_) | `text/plain` |
+| `.vsd` | Microsoft Visio | `application/vnd.visio` |
+| `.wav` | Waveform Audio Format | `audio/wav` |
+| `.weba` | WEBM audio | `audio/webm` |
+| `.webm` | WEBM video | `video/webm` |
+| `.webp` | WEBP image | `image/webp` |
+| `.woff` | Web Open Font Format (WOFF) | `font/woff` |
+| `.woff2` | Web Open Font Format (WOFF) | `font/woff2` |
+| `.xhtml` | XHTML | `application/xhtml+xml` |
+| `.xls` | Microsoft Excel | `application/vnd.ms-excel` |
+| `.xlsx` | Microsoft Excel (OpenXML) | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
+| `.xml` | `XML` | `application/xml` if _not_ readable from casual users ([RFC 3023](https://datatracker.ietf.org/doc/html/rfc3023#section-3), section 3) `text/xml` if readable from casual users ([RFC 3023](https://datatracker.ietf.org/doc/html/rfc3023#section-3), section 3) |
+| `.xul` | XUL | `application/vnd.mozilla.xul+xml` |
+| `.zip` | ZIP archive | `application/zip` |
+| `.3gp` | [3GPP](https://en.wikipedia.org/wiki/3GP_and_3G2) audio/video container | `video/3gpp` `audio/3gpp` if it doesn't contain video |
+| `.3g2` | [3GPP2](https://en.wikipedia.org/wiki/3GP_and_3G2) audio/video container | `video/3gpp2` `audio/3gpp2` if it doesn't contain video |
+| `.7z` | [7-zip](https://en.wikipedia.org/wiki/7-Zip) archive | `application/x-7z-compressed` |
diff --git a/files/en-us/web/http/basics_of_http/mime_types/index.html b/files/en-us/web/http/basics_of_http/mime_types/index.html
deleted file mode 100644
index 601c249097e353d..000000000000000
--- a/files/en-us/web/http/basics_of_http/mime_types/index.html
+++ /dev/null
@@ -1,566 +0,0 @@
----
-title: MIME types (IANA media types)
-slug: Web/HTTP/Basics_of_HTTP/MIME_types
-tags:
- - Content-Type
- - Guide
- - HTTP
- - MIME Types
- - Meta
- - Request header
- - Response Header
- - application/javascript
- - application/json
- - application/xml
----
-
-
-
-
- Extension
- Kind of document
- MIME Type
-
-
-
- .aac
AAC audio
-
- audio/aac
-
-
- .abw
AbiWord document
-
- application/x-abiword
-
-
- .arc
Archive document (multiple files embedded)
-
- application/x-freearc
-
-
- .avi
AVI: Audio Video Interleave
-
- video/x-msvideo
-
-
- .azw
Amazon Kindle eBook format
-
- application/vnd.amazon.ebook
-
-
- .bin
Any kind of binary data
-
- application/octet-stream
-
-
- .bmp
Windows OS/2 Bitmap Graphics
-
- image/bmp
-
-
- .bz
BZip archive
-
- application/x-bzip
-
-
- .bz2
BZip2 archive
-
- application/x-bzip2
-
-
- .cda
CD audio
-
- application/x-cdf
-
-
- .csh
C-Shell script
-
- application/x-csh
-
-
- .css
Cascading Style Sheets (CSS)
-
- text/css
-
-
- .csv
Comma-separated values (CSV)
-
- text/csv
-
-
- .doc
Microsoft Word
-
- application/msword
-
-
- .docx
Microsoft Word (OpenXML)
-
- application/vnd.openxmlformats-officedocument.wordprocessingml.document
-
-
- .eot
MS Embedded OpenType fonts
-
- application/vnd.ms-fontobject
-
-
- .epub
Electronic publication (EPUB)
-
- application/epub+zip
-
-
- .gz
GZip Compressed Archive
-
- application/gzip
-
-
- .gif
Graphics Interchange Format (GIF)
-
- image/gif
-
-
- .htm
- .htmlHyperText Markup Language (HTML)
-
- text/html
-
-
- .ico
Icon format
-
- image/vnd.microsoft.icon
-
-
- .ics
iCalendar format
-
- text/calendar
-
-
- .jar
Java Archive (JAR)
-
- application/java-archive
-
-
- .jpeg
- .jpg
JPEG images
-
- image/jpeg
-
-
- .js
JavaScript
-
-
- text/javascript
(Specifications: HTML and its reasoning, and IETF)
-
-
-
- .json
JSON format
-
- application/json
-
-
- .jsonld
JSON-LD format
-
- application/ld+json
-
-
- .mid
- .midi
Musical Instrument Digital Interface (MIDI)
-
- audio/midi
audio/x-midi
-
-
- .mjs
JavaScript module
-
- text/javascript
-
-
- .mp3
MP3 audio
-
- audio/mpeg
-
-
- .mp4
MP4 audio
-
- video/mp4
-
-
- .mpeg
MPEG Video
-
- video/mpeg
-
-
- .mpkg
Apple Installer Package
-
- application/vnd.apple.installer+xml
-
-
- .odp
OpenDocument presentation document
-
- application/vnd.oasis.opendocument.presentation
-
-
- .ods
OpenDocument spreadsheet document
-
- application/vnd.oasis.opendocument.spreadsheet
-
-
- .odt
OpenDocument text document
-
- application/vnd.oasis.opendocument.text
-
-
- .oga
OGG audio
-
- audio/ogg
-
-
- .ogv
OGG video
-
- video/ogg
-
-
- .ogx
OGG
-
- application/ogg
-
-
- .opus
Opus audio
-
- audio/opus
-
-
- .otf
OpenType font
-
- font/otf
-
-
- .png
Portable Network Graphics
-
- image/png
-
-
- .pdf
Adobe Portable Document Format (PDF)
-
- application/pdf
-
-
- .php
Hypertext Preprocessor (Personal Home Page)
-
- application/x-httpd-php
-
-
- .ppt
Microsoft PowerPoint
-
- application/vnd.ms-powerpoint
-
-
- .pptx
Microsoft PowerPoint (OpenXML)
-
- application/vnd.openxmlformats-officedocument.presentationml.presentation
-
-
- .rar
RAR archive
-
- application/vnd.rar
-
-
- .rtf
Rich Text Format (RTF)
-
- application/rtf
-
-
- .sh
Bourne shell script
-
- application/x-sh
-
-
- .svg
Scalable Vector Graphics (SVG)
-
- image/svg+xml
-
-
- .swf
Small web format (SWF) or Adobe Flash document
-
- application/x-shockwave-flash
-
-
- .tar
Tape Archive (TAR)
-
- application/x-tar
-
-
- .tif
- .tiffTagged Image File Format (TIFF)
-
- image/tiff
-
-
- .ts
MPEG transport stream
-
- video/mp2t
-
-
- .ttf
TrueType Font
-
- font/ttf
-
-
- .txt
Text, (generally ASCII or ISO 8859-n)
-
- text/plain
-
-
- .vsd
Microsoft Visio
-
- application/vnd.visio
-
-
- .wav
Waveform Audio Format
-
- audio/wav
-
-
- .weba
WEBM audio
-
- audio/webm
-
-
- .webm
WEBM video
-
- video/webm
-
-
- .webp
WEBP image
-
- image/webp
-
-
- .woff
Web Open Font Format (WOFF)
-
- font/woff
-
-
- .woff2
Web Open Font Format (WOFF)
-
- font/woff2
-
-
- .xhtml
XHTML
-
- application/xhtml+xml
-
-
- .xls
Microsoft Excel
-
- application/vnd.ms-excel
-
-
- .xlsx
Microsoft Excel (OpenXML)
-
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
-
-
- .xml
- XML
- application/xml
if not readable from casual users (RFC 3023, section 3)
- text/xml
if readable from casual users (RFC 3023, section 3)
-
-
- .xul
XUL
-
- application/vnd.mozilla.xul+xml
-
-
- .zip
ZIP archive
-
- application/zip
-
-
- .3gp
3GPP audio/video container
-
- video/3gpp
- audio/3gpp
if it doesn't contain video
-
-
- .3g2
3GPP2 audio/video container
-
- video/3gpp2
- audio/3gpp2
if it doesn't contain video
-
-
-
- .7z
7-zip archive
-
- application/x-7z-compressed
Structure of a MIME type
-
-/
) between them,
- comprise a MIME type. No whitespace is allowed in a MIME type:type/subtype
-
-video
or text
. The
- subtype identifies the exact kind of data of the specified
- type the MIME type represents. For example, for the MIME type text
, the
- subtype might be plain
(plain text), html
- ({{Glossary("HTML")}} source code), or calendar
(for
- iCalendar/.ics
) files.type/subtype;parameter=value
-
-text
, the optional
- charset
parameter can be used to specify the character set used for the
- characters in the data. If no charset
is specified, the default is
- {{Glossary("ASCII")}} (US-ASCII
) unless overridden by the {{Glossary("user
- agent", "user agent's")}} settings. To specify a UTF-8 text file, the MIME type
- text/plain;charset=UTF-8
is used.Types
-
-Discrete types
-
-
-
-
-application
- application/octet-stream
.
- Other common examples include application/pdf
,
- application/pkcs8
, and application/zip
.
- (Registration at IANA)
- audio
- audio/mpeg
,
- audio/vorbis
.
- (Registration at IANA)
- example
- example
can also be used as a subtype; for instance, in an example
- related to working with audio on the web, the MIME type audio/example
can
- be used to indicate that the type is a placeholder and should be replaced with an
- appropriate one when using the code in the real world.
- font
- font/woff
,
- font/ttf
, and font/otf
.
- (Registration at IANA)
- image
- image/jpeg
, image/png
, and
- image/svg+xml
.
- (Registration at IANA)
- model
- model/3mf
and
- model/vrml
.
- (Registration at IANA)
- text
- text/plain
, text/csv
, and text/html
.
- (Registration at IANA)
- video
- video/mp4
).
- (Registration at IANA)
- text/plain
should be used.
- Similarly, for binary documents without a specific or known subtype,
- application/octet-stream
should be used.Multipart types
-
-multipart/form-data
, used in
- the {{HTTPMethod("POST")}} method of HTML
- Forms, and multipart/byteranges
, used with {{HTTPStatus("206")}}
- Partial Content
to send part of a document, HTTP doesn't handle multipart
- documents in a special way: the message is transmitted to the browser (which will likely
- show a "Save As" window if it doesn't know how to display the document).
-
-
-message
- message/rfc822
(for forwarded or replied-to message quoting) and
- message/partial
to allow breaking a large message into smaller ones
- automatically to be reassembled by the recipient.
- (Registration at IANA)
- multipart
- multipart/form-data
(for data produced using
- the {{domxref("FormData")}} API) and multipart/byteranges
(defined in
- {{RFC(7233, "5.4.1")}} and used with {{Glossary("HTTP")}}'s {{HTTPStatus(206)}}
- "Partial Content" response returned when the fetched data is only part of the content,
- such as is delivered using the {{HTTPHeader("Range")}} header).
- (Registration at IANA)
- Important MIME types for Web developers
-
-
-application/octet-stream
-
-attachment
, and propose a "Save As" dialog.text/plain
-
-text/plain
does not mean "any kind of textual data." If they
- expect a specific kind of textual data, they will likely not consider it a match.
- Specifically if they download a text/plain
file from a
- {{HTMLElement("link")}} element declaring a CSS file, they will not recognize it as a
- valid CSS file if presented with text/plain
. The CSS mime type
- text/css
must be used.text/css
-
-text/css
. If a server doesn't recognize the .css
suffix for
- CSS files, it may send them with text/plain
or
- application/octet-stream
MIME types. If so, they won't be recognized as CSS
- by most browsers and will be ignored.text/html
-
-application/xhtml+xml
) are mostly useless nowadays.application/xml
or
- application/xhtml+xml
if you want XML's strict parsing rules,
- <![CDATA[…]]>
- sections, or elements that aren't from HTML/SVG/MathML namespaces.text/javascript
-
-text/javascript
. No other values are considered valid, and using any
- of those may result in scripts that do not load or run.
-
-
-application/javascript
application/ecmascript
application/x-ecmascript
{{Non-standard_Inline}}application/x-javascript
{{Non-standard_Inline}}text/javascript
text/ecmascript
text/javascript1.0
{{Non-standard_Inline}}text/javascript1.1
{{Non-standard_Inline}}text/javascript1.2
{{Non-standard_Inline}}text/javascript1.3
{{Non-standard_Inline}}text/javascript1.4
{{Non-standard_Inline}}text/javascript1.5
{{Non-standard_Inline}}text/jscript
{{Non-standard_Inline}}text/livescript
{{Non-standard_Inline}}text/x-ecmascript
{{Non-standard_Inline}}text/x-javascript
{{Non-standard_Inline}}text/javascript
. It's the only
- MIME type guaranteed to work now and into the future.charset
parameter at the end of the
- text/javascript
media type, to specify the character set used to represent
- the code's content. This is not valid, and in most cases will result in a script not
- being loaded.Image types
-
-image
contain image data. The subtype specifies
- which specific image file format the data represents. Only a few image types are used
- commonly enough to be considered safe for use on web pages:Audio and video types
-
-
-
-
-
-
-
-
-
- MIME type
- Audio or video type
-
-
-
- audio/wave
- audio/wav
- audio/x-wav
- audio/x-pn-wav
- An audio file in the WAVE container format. The PCM audio codec (WAVE codec "1")
- is often supported, but other codecs have limited support (if any).
-
-
-
- audio/webm
An audio file in the WebM container format. Vorbis and Opus are the codecs
- officially supported by the WebM specification.
-
-
-
- video/webm
A video file, possibly with audio, in the WebM container format. VP8 and VP9 are
- the most common video codecs; Vorbis and Opus the most common audio codecs.
-
-
-
- audio/ogg
An audio file in the Ogg container format. Vorbis is the most common audio codec
- used in such a container; however, Opus is now supported by Ogg as well.
-
-
-
- video/ogg
A video file, possibly with audio, in the Ogg container format. Theora is the
- usual video codec used within it; Vorbis is the usual audio codec, although Opus
- is becoming more common.
-
-
-
-
- application/ogg
An audio or video file using the Ogg container format. Theora is the usual video
- codec used within it; Vorbis is the usual audio codec.
- multipart/form-data
-
-multipart/form-data
type can be used when sending the values of a
- completed HTML Form from browser to
- server.--
). Each part is its own entity with
- its own HTTP headers, {{HTTPHeader("Content-Disposition")}}, and
- {{HTTPHeader("Content-Type")}} for file uploading fields.Content-Type: multipart/form-data; boundary=aBoundaryString
-(other headers associated with the multipart document as a whole)
-
---aBoundaryString
-Content-Disposition: form-data; name="myFile"; filename="img.jpg"
-Content-Type: image/jpeg
-
-(data)
---aBoundaryString
-Content-Disposition: form-data; name="myField"
-
-(data)
---aBoundaryString
-(more subparts)
---aBoundaryString--
-
-
-
-<form>
:<form action="http://localhost:8000/" method="post" enctype="multipart/form-data">
- <label>Name: <input name="myTextField" value="Test"></label>
- <label><input type="checkbox" name="myCheckBox"> Check</label>
- <label>Upload file: <input type="file" name="myFile" value="test.txt"></label>
- <button>Send the file</button>
-</form>
-
-POST / HTTP/1.1
-Host: localhost:8000
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate
-Connection: keep-alive
-Upgrade-Insecure-Requests: 1
-Content-Type: multipart/form-data; boundary=---------------------------8721656041911415653955004498
-Content-Length: 465
-
------------------------------8721656041911415653955004498
-Content-Disposition: form-data; name="myTextField"
-
-Test
------------------------------8721656041911415653955004498
-Content-Disposition: form-data; name="myCheckBox"
-
-on
------------------------------8721656041911415653955004498
-Content-Disposition: form-data; name="myFile"; filename="test.txt"
-Content-Type: text/plain
-
-Simple file.
------------------------------8721656041911415653955004498--
-
-
-
-multipart/byteranges
-
-multipart/byteranges
MIME type is used to send partial responses to
- the browser. Partial Content
status code is sent, this
- MIME type indicates that the document is composed of several parts, one for each of the
- requested ranges. Like other multipart types, the {{HTTPHeader("Content-Type")}} uses a
- boundary
to separate the pieces. Each piece has a
- {{HTTPHeader("Content-Type")}} header with its actual type and a
- {{HTTPHeader("Content-Range")}} of the range it represents.
-
-HTTP/1.1 206 Partial Content
-Accept-Ranges: bytes
-Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
-Content-Length: 385
-
---3d6b6a416f9b5
-Content-Type: text/html
-Content-Range: bytes 100-200/1270
-
-eta http-equiv="Content-type" content="text/html; charset=utf-8" />
- <meta name="vieport" content
---3d6b6a416f9b5
-Content-Type: text/html
-Content-Range: bytes 300-400/1270
-
--color: #f0f0f2;
- margin: 0;
- padding: 0;
- font-family: "Open Sans", "Helvetica
---3d6b6a416f9b5--
Importance of setting the correct
- MIME type
-
-application/octet-stream
MIME type. For security reasons, most browsers do
- not allow setting a custom default action for such resources, forcing the user to save
- it to disk to use it.
-
-
-application/x-rar-compressed
.application/octet-stream
as most
- browsers do not allow defining a default behavior (like "Open in Word") for this
- generic MIME type. A specific type like application/vnd.mspowerpoint
- lets users open such files automatically in the presentation software of their
- choice.MIME sniffing
-
-Other methods of conveying document type
-
-
-
-
-
-47 49 46 38 39
hexadecimal value (GIF89
), and PNG files with
- 89 50 4E 47
(.PNG
). Not all file types have magic numbers,
- so this is not 100% reliable either.See also
-
-
diff --git a/files/en-us/web/http/basics_of_http/mime_types/index.md b/files/en-us/web/http/basics_of_http/mime_types/index.md
new file mode 100644
index 000000000000000..2b3cee70ce4c468
--- /dev/null
+++ b/files/en-us/web/http/basics_of_http/mime_types/index.md
@@ -0,0 +1,449 @@
+---
+title: MIME types (IANA media types)
+slug: Web/HTTP/Basics_of_HTTP/MIME_types
+tags:
+ - Content-Type
+ - Guide
+ - HTTP
+ - MIME Types
+ - Meta
+ - Request header
+ - Response Header
+ - application/javascript
+ - application/json
+ - application/xml
+---
+{{HTTPSidebar}}
+
+A **media type** (also known as a
+**Multipurpose Internet Mail Extensions or MIME type**) is a standard
+that indicates the nature and format of a document, file, or assortment of
+bytes. It is defined and standardized in IETF's {{RFC(6838)}}.
+
+The [Internet Assigned Numbers Authority (IANA)](https://www.iana.org/) is
+responsible for all official MIME types, and you can find the most up-to-date and
+complete list at their [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml)
+page.
+
+> **Warning:** Browsers use the MIME type,
+> _not the file extension_,
+> to determine how to process a URL,
+> so it's important
+> that web servers send the correct MIME type in the response's {{HTTPHeader("Content-Type")}} header.
+> If this is not correctly configured,
+> browsers are likely to misinterpret the contents of files,
+> sites will not work correctly,
+> and downloaded files may be mishandled.
+
+## Structure of a MIME type
+
+The simplest MIME type consists of a _type_ and a _subtype_; these
+are each strings which, when concatenated with a slash (`/`) between them,
+comprise a MIME type. No whitespace is allowed in a MIME type:
+
+```
+type/subtype
+```
+
+The **_type_** represents the general category into which the
+data type falls, such as `video` or `text`. The
+**_subtype_** identifies the exact kind of data of the specified
+type the MIME type represents. For example, for the MIME type `text`, the
+subtype might be `plain` (plain text), `html`
+({{Glossary("HTML")}} source code), or `calendar` (for
+iCalendar/`.ics`) files.
+
+Each type has its own set of possible subtypes, and a MIME type always has both a type
+and a subtype, never just one or the other.
+
+An optional **parameter** can be added to provide additional details:
+
+```
+type/subtype;parameter=value
+```
+
+For example, for any MIME type whose main type is `text`, the optional
+`charset` parameter can be used to specify the character set used for the
+characters in the data. If no `charset` is specified, the default is
+{{Glossary("ASCII")}} (`US-ASCII`) unless overridden by the {{Glossary("user
+ agent", "user agent's")}} settings. To specify a UTF-8 text file, the MIME type
+`text/plain;charset=UTF-8` is used.
+
+MIME types are case-insensitive but are traditionally written in lowercase, with the
+exception of parameter values, whose case may or may not have specific meaning.
+
+### Types
+
+There are two classes of type: **discrete** and
+**multipart**. Discrete types are types which represent a single file or
+medium, such as a single text or music file, or a single video. A multipart type is one
+which represents a document that's comprised of multiple component parts, each of which
+may have its own individual MIME type; or, a multipart type may encapsulate multiple
+files being sent together in one transaction. For example, multipart MIME types are used
+when attaching multiple files to an email.
+
+#### Discrete types
+
+The discrete types currently registered with the IANA are:
+
+- `application`
+ - : Any kind of binary data that doesn't fall explicitly into one of the other types;
+ either data that will be executed or interpreted in some way or binary data that
+ requires a specific application or category of application to use. Generic binary data
+ (or binary data whose true type is unknown) is `application/octet-stream`.
+ Other common examples include `application/pdf`,
+ `application/pkcs8`, and `application/zip`.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#application)
+- `audio`
+ - : Audio or music data. Examples include `audio/mpeg`,
+ `audio/vorbis`.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#audio)
+- `example`
+ - : Reserved for use as a placeholder in examples showing how to use MIME types. These
+ should never be used outside of sample code listings and documentation.
+ `example` can also be used as a subtype; for instance, in an example
+ related to working with audio on the web, the MIME type `audio/example` can
+ be used to indicate that the type is a placeholder and should be replaced with an
+ appropriate one when using the code in the real world.
+- `font`
+ - : Font/typeface data. Common examples include `font/woff`,
+ `font/ttf`, and `font/otf`.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#font)
+- `image`
+ - : Image or graphical data including both bitmap and vector still images as well as
+ animated versions of still image formats such as animated {{Glossary("GIF")}} or APNG.
+ Common examples are `image/jpeg`, `image/png`, and
+ `image/svg+xml`.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#image)
+- `model`
+ - : Model data for a 3D object or scene. Examples include `model/3mf` and
+ `model/vrml`.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#model)
+- `text`
+ - : Text-only data including any human-readable content, source code, or textual data
+ such as comma-separated value (CSV) formatted data. Examples include
+ `text/plain`, `text/csv`, and `text/html`.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#text)
+- `video`
+ - : Video data or files, such as MP4 movies (`video/mp4`).
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#video)
+
+For text documents without a specific subtype, `text/plain` should be used.
+Similarly, for binary documents without a specific or known subtype,
+`application/octet-stream` should be used.
+
+#### Multipart types
+
+**Multipart** types indicate a category of document broken into
+pieces, often with different MIME types; they can also be used — especially in email
+scenarios — to represent multiple, separate files which are all part of the same
+transaction. They represent a **composite document**.
+
+With the exception of `multipart/form-data`, used in
+the {{HTTPMethod("POST")}} method of [HTML
+Forms](/en-US/docs/Learn/Forms), and `multipart/byteranges`, used with {{HTTPStatus("206")}}
+`Partial Content` to send part of a document, HTTP doesn't handle multipart
+documents in a special way: the message is transmitted to the browser (which will likely
+show a "Save As" window if it doesn't know how to display the document).
+
+There are two multipart types:
+
+- `message`
+ - : A message that encapsulates other messages. This can be used, for instance, to
+ represent an email that includes a forwarded message as part of its data, or to allow
+ sending very large messages in chunks as if it were multiple messages. Examples
+ include `message/rfc822` (for forwarded or replied-to message quoting) and
+ `message/partial` to allow breaking a large message into smaller ones
+ automatically to be reassembled by the recipient.
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#message)
+- `multipart`
+ - : Data that is comprised of multiple components which may individually have different
+ MIME types. Examples include `multipart/form-data` (for data produced using
+ the {{domxref("FormData")}} API) and `multipart/byteranges` (defined in
+ {{RFC(7233, "5.4.1")}} and used with {{Glossary("HTTP")}}'s {{HTTPStatus(206)}}
+ "Partial Content" response returned when the fetched data is only part of the content,
+ such as is delivered using the {{HTTPHeader("Range")}} header).
+ [(Registration at IANA)](https://www.iana.org/assignments/media-types/media-types.xhtml#multipart)
+
+## Important MIME types for Web developers
+
+### application/octet-stream
+
+This is the default for binary files. As it means _unknown binary_ file,
+browsers usually don't execute it, or even ask if it should be executed. They treat it
+as if the {{HTTPHeader("Content-Disposition")}} header was set to
+`attachment`, and propose a "Save As" dialog.
+
+### text/plain
+
+This is the default for textual files. Even if it really means "unknown textual file,"
+browsers assume they can display it.
+
+> **Note:** `text/plain` does not mean "any kind of textual data." If they
+> expect a specific kind of textual data, they will likely not consider it a match.
+> Specifically if they download a `text/plain` file from a
+> {{HTMLElement("link")}} element declaring a CSS file, they will not recognize it as a
+> valid CSS file if presented with `text/plain`. The CSS mime type
+> `text/css` must be used.
+
+### text/css
+
+CSS files used to style a Web page **must** be sent with
+`text/css`. If a server doesn't recognize the `.css` suffix for
+CSS files, it may send them with `text/plain` or
+`application/octet-stream` MIME types. If so, they won't be recognized as CSS
+by most browsers and will be ignored.
+
+### text/html
+
+All HTML content should be served with this type. Alternative MIME types for XHTML
+(like `application/xhtml+xml`) are mostly useless nowadays.
+
+> **Note:** Use `application/xml` or
+> `application/xhtml+xml` if you want XML's strict parsing rules,
+> [``](/en-US/docs/Web/API/CDATASection)
+> sections, or elements that aren't from HTML/SVG/MathML namespaces.
+
+### text/javascript
+
+Per the HTML specification, JavaScript files should always be served using the MIME
+type `text/javascript`. No other values are considered valid, and using any
+of those may result in scripts that do not load or run.
+
+For historical reasons, the [MIME Sniffing
+Standard](https://mimesniff.spec.whatwg.org/) (the definition of how browsers should interpret media types and figure
+out what to do with content that doesn't have a valid one) allows JavaScript to be
+served using any MIME type that essentially matches any of the following:
+
+- `application/javascript`
+- `application/ecmascript`
+- `application/x-ecmascript` {{Non-standard_Inline}}
+- `application/x-javascript` {{Non-standard_Inline}}
+- `text/javascript`
+- `text/ecmascript`
+- `text/javascript1.0` {{Non-standard_Inline}}
+- `text/javascript1.1` {{Non-standard_Inline}}
+- `text/javascript1.2` {{Non-standard_Inline}}
+- `text/javascript1.3` {{Non-standard_Inline}}
+- `text/javascript1.4` {{Non-standard_Inline}}
+- `text/javascript1.5` {{Non-standard_Inline}}
+- `text/jscript` {{Non-standard_Inline}}
+- `text/livescript` {{Non-standard_Inline}}
+- `text/x-ecmascript` {{Non-standard_Inline}}
+- `text/x-javascript` {{Non-standard_Inline}}
+
+> **Note:** Even though any given {{Glossary("user agent")}} may support
+> any or all of these, you should only use `text/javascript`. It's the only
+> MIME type guaranteed to work now and into the future.
+
+Some content you find may have a `charset` parameter at the end of the
+`text/javascript` media type, to specify the character set used to represent
+the code's content. This is not valid, and in most cases will result in a script not
+being loaded.
+
+### Image types
+
+Files whose MIME type is `image` contain image data. The subtype specifies
+which specific image file format the data represents. Only a few image types are used
+commonly enough to be considered safe for use on web pages:
+
+{{page("en-US/docs/Web/Media/Formats/Image_types", "table-of-image-file-types")}}
+
+### Audio and video types
+
+As is the case for images, HTML doesn't mandate that web browsers support any specific
+file and codec types for the {{HTMLElement("audio")}} and {{HTMLElement("video")}}
+elements, so it's important to consider your target audience and the range of browsers
+(and versions of those browsers) they may be using when choosing the file type and
+codecs to use for media.
+
+Our [media container formats
+guide](/en-US/docs/Web/Media/Formats/Containers) provides a list of the file types that are commonly supported by web
+browsers, including information about what their special use cases may be, any drawbacks
+they have, and compatibility information, along with other details.
+
+The [audio codec](/en-US/docs/Web/Media/Formats/Audio_codecs) and [video codec](/en-US/docs/Web/Media/Formats/Video_codecs) guides list the
+various codecs that web browsers often support, providing compatibility details along
+with technical information such as how many audio channels they support, what sort of
+compression is used, and what bit rates and so forth they're useful at. The [codecs used by WebRTC](/en-US/docs/Web/Media/Formats/WebRTC_codecs) guide
+expands upon this by specifically covering the codecs supported by the major web
+browsers, so you can choose the codecs that best cover the range of browsers you wish to
+support.
+
+As for MIME types of audio or video files, they typically specify the container format
+(file type). The optional [codecs parameter](/en-US/docs/Web/Media/Formats/codecs_parameter) can be
+added to the MIME type to further specify which codecs to use and what options were used
+to encode the media, such as codec profile, level, or other such information.
+
+The most commonly used MIME types used for web content are listed below. This isn't a
+complete list of all the types that may be available, however. See the [media container formats](/en-US/docs/Web/Media/Formats/Containers) guide for
+that.
+
+| MIME type | Audio or video type |
+| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `audio/wave` `audio/wav` `audio/x-wav` `audio/x-pn-wav` | An audio file in the WAVE container format. The PCM audio codec (WAVE codec "1") is often supported, but other codecs have limited support (if any). |
+| `audio/webm` | An audio file in the WebM container format. Vorbis and Opus are the codecs officially supported by the WebM specification. |
+| `video/webm` | A video file, possibly with audio, in the WebM container format. VP8 and VP9 are the most common video codecs; Vorbis and Opus the most common audio codecs. |
+| `audio/ogg` | An audio file in the Ogg container format. Vorbis is the most common audio codec used in such a container; however, Opus is now supported by Ogg as well. |
+| `video/ogg` | A video file, possibly with audio, in the Ogg container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec, although Opus is becoming more common. |
+| `application/ogg` | An audio or video file using the Ogg container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec. |
+
+### multipart/form-data
+
+The `multipart/form-data` type can be used when sending the values of a
+completed [HTML Form](/en-US/docs/Learn/Forms) from browser to
+server.
+
+As a multipart document format, it consists of different parts, delimited by a boundary
+(a string starting with a double dash `--`). Each part is its own entity with
+its own HTTP headers, {{HTTPHeader("Content-Disposition")}}, and
+{{HTTPHeader("Content-Type")}} for file uploading fields.
+
+```
+Content-Type: multipart/form-data; boundary=aBoundaryString
+(other headers associated with the multipart document as a whole)
+
+--aBoundaryString
+Content-Disposition: form-data; name="myFile"; filename="img.jpg"
+Content-Type: image/jpeg
+
+(data)
+--aBoundaryString
+Content-Disposition: form-data; name="myField"
+
+(data)
+--aBoundaryString
+(more subparts)
+--aBoundaryString--
+```
+
+The following `
+```
+
+will send this message:
+
+```
+POST / HTTP/1.1
+Host: localhost:8000
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+Accept-Language: en-US,en;q=0.5
+Accept-Encoding: gzip, deflate
+Connection: keep-alive
+Upgrade-Insecure-Requests: 1
+Content-Type: multipart/form-data; boundary=---------------------------8721656041911415653955004498
+Content-Length: 465
+
+-----------------------------8721656041911415653955004498
+Content-Disposition: form-data; name="myTextField"
+
+Test
+-----------------------------8721656041911415653955004498
+Content-Disposition: form-data; name="myCheckBox"
+
+on
+-----------------------------8721656041911415653955004498
+Content-Disposition: form-data; name="myFile"; filename="test.txt"
+Content-Type: text/plain
+
+Simple file.
+-----------------------------8721656041911415653955004498--
+```
+
+### multipart/byteranges
+
+The `multipart/byteranges` MIME type is used to send partial responses to
+the browser.
+
+When the {{HTTPStatus("206", "206 Partial Content")}} status code is sent, this
+MIME type indicates that the document is composed of several parts, one for each of the
+requested ranges. Like other multipart types, the {{HTTPHeader("Content-Type")}} uses a
+`boundary` to separate the pieces. Each piece has a
+{{HTTPHeader("Content-Type")}} header with its actual type and a
+{{HTTPHeader("Content-Range")}} of the range it represents.
+
+```
+HTTP/1.1 206 Partial Content
+Accept-Ranges: bytes
+Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
+Content-Length: 385
+
+--3d6b6a416f9b5
+Content-Type: text/html
+Content-Range: bytes 100-200/1270
+
+eta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ {{HTTPSidebar}}{{non-standard_header}}
Resource URLs, URLs prefixed with the resource:
scheme, are used by
- Firefox and Firefox browser extensions to load resources internally, but some of the
- information is available to sites the browser connects to as well.
Resource URLs are composed of two parts: a prefix (resource:
), and a URL
- pointing to the resource you want to load:
resource://<url>- -
An example:
- -resource://gre/res/svg.css- -
When arrows are found in the resource URL's ('->'), it means that the first file - loaded the next one:
- -resource://<File-loader> -> <File-loaded>- -
Please refer to Identifying - resources on the web for more general details.
- -In this article, we focus on resource URIs, which are used internally by Firefox to - point to built-in resources.
- -Because some of the information shared by resource:
URLs is available to
- websites, a web page could run internal scripts and inspect internal resources of
- Firefox, including the default preferences, which could be a serious security and
- privacy issue.
For example, a script on - Browserleaks highlights what Firefox reveals when queried by a simple script - running on the site (you can find the code in https://browserleaks.com/firefox#more). -
- -The file firefox.js passes preference names and values to the pref() function. For - example:
- -http://searchfox.org/mozilla-central/rev/48ea452803907f2575d81021e8678634e8067fc2/browser/app/profile/firefox.js#575- -
Web sites can easily collect Firefox default preferences by overriding this
- pref()
function and using the script
- resource:///defaults/preferences/firefox.js
.
Furthermore, some default values of preferences differ between build configurations, - such as platform and locale, which means web sites could identify individual users using - this information.
- -In order to fix this problem, Mozilla changed the behavior of loading resource: URIs in - {{bug(863246)}}, which landed in Firefox 57 (Quantum).
- -In the past, web content was able to access whatever resource:
URIs were
- desired — not only Firefox’s internal resources, but also extensions’ assets. Now this
- behavior is prohibited by default.
It is however still necessary for Firefox to load resources in web content under
- certain circumstances. For example, if you open the view source page (View Page Source
- or View Selection Source), you will find it requires viewsource.css
through
- a resource:
URI. Resources that have to be exposed to web content have
- been moved to a new location named resource://content-accessible/
, which is
- isolated and only contains non-sensitive resources. In this way we can keep essential
- resources exposed and have most threats eliminated.
Note: It is recommended that web and extension developers don't try - to use resource URLs anymore. Their usage was hacky at best, and most usage won't work - any more.
-resource: is not defined in any specification.
- -resource: is Firefox only.
- -resource:
is covered here)
- Serving different Web pages or services to different browsers is usually a bad idea. The Web is meant to be accessible to everyone, regardless of which browser or device they're using. There are ways to develop your website to progressively enhance itself based on the availability of features rather than by targeting specific browsers.
- -But browsers and standards are not perfect, and there are still some edge cases where detecting the browser is needed. Using the user agent to detect the browser looks simple, but doing it well is, in fact, a very hard problem. This document will guide you in doing this as correctly as possible.
- -Note: It's worth re-iterating: it's very rarely a good idea to use user agent sniffing. You can almost always find a better, more broadly compatible way to solve your problem!
-When considering using the user agent string to detect which browser is being used, your first step is to try to avoid it if possible. Start by trying to identify why you want to do it.
- -If you want to avoid using user agent detection, you have options!
- -// this code snippet splits a string in a special notation - -if (navigator.userAgent.indexOf("Chrome") !== -1){ - // YES! The user is suspected to support look-behind regexps - // DO NOT USE /(?<=[A-Z])/. It will cause a syntax error in - // browsers that do not support look-behind expressions - // because all browsers parse the entire script, including - // sections of the code that are never executed. - var camelCaseExpression = new RegExp("(?<=[A-Z])"); - var splitUpString = function(str) { - return (""+str).split(camelCaseExpression); - }; -} else { - /*This fallback code is much less performant, but works*/ - var splitUpString = function(str){ - return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g); - }; -} -console.log(splitUpString("fooBare")); // ["fooB", "are"] -console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"]- -
- The above code would have made several incorrect assumptions: - First, it assumed that all user agent strings that include the substring "Chrome" are Chrome. UA strings are notoriously misleading. - Then, it assumed that the lookbehind feature would always be available if the browser was Chrome. The agent might be an older version of Chrome, from before support was added, or (because the feature was experimental at the time) it could be a later version of Chrome that removed it. - Most importantly, it assumed no other browsers would support the feature. Support could have been added to other browsers at any time, but this code would have continued choosing the inferior path. -
- -Problems like these can be avoided by testing for support of the feature itself instead:
- -var isLookBehindSupported = false; - -try { - new RegExp("(?<=)"); - isLookBehindSupported = true; -} catch (err) { - // If the agent doesn't support lookbehinds, the attempted - // creation of a RegExp object using that syntax throws and - // isLookBehindSupported remains false. -} - -var splitUpString = isLookBehindSupported ? function(str) { - return (""+str).split(new RegExp("(?<=[A-Z])")); -} : function(str) { - return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g); -}; -- -
As the above code demonstrates, there is always a way to test browser support without user agent sniffing. There is never any reason to check the user agent string for this.
- -Lastly, the above code snippets bring about a critical issue with cross-browser coding that must always be taken into account. Don't unintentionally use the API you are testing for in unsupported browsers. This may sound obvious and simple, but sometimes it is not. For example, in the above code snippets, using lookbehind in short-regexp notation (e.g. /reg/igm) will cause a parser error in unsupported browsers. Thus, in the above example, you would use new RegExp("(?<=look_behind_stuff)"); instead of /(?<=look_behind_stuff)/, even in the lookbehind supported section of your code.
-var hasTouchScreen = false; -if ("maxTouchPoints" in navigator) { - hasTouchScreen = navigator.maxTouchPoints > 0; -} else if ("msMaxTouchPoints" in navigator) { - hasTouchScreen = navigator.msMaxTouchPoints > 0; -} else { - var mQ = window.matchMedia && matchMedia("(pointer:coarse)"); - if (mQ && mQ.media === "(pointer:coarse)") { - hasTouchScreen = !!mQ.matches; - } else if ('orientation' in window) { - hasTouchScreen = true; // deprecated, but good fallback - } else { - // Only as a last resort, fall back to user agent sniffing - var UA = navigator.userAgent; - hasTouchScreen = ( - /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) || - /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA) - ); - } -} -if (hasTouchScreen) - document.getElementById("exampleButton").style.padding="1em";-
As for the screen size, use window.innerWidth and window.addEventListener("resize", function(){ /*refresh screen size dependent things*/ }). What you want to do for screen size is not slash off information on smaller screens. That will only annoy people because it will force them to use the desktop version. Rather, try to have fewer columns of information in a longer page on smaller screens while having more columns with a shorter page on larger screen sizes. This effect can be easily achieved using CSS flexboxes, sometimes with floats as a partial fallback.
-Also try to move less relevant/important information down to the bottom and group the page's content together meaningfully. Although it is off-topic, perhaps the following detailed example might give you insights and ideas that persuade you to forgo user agent sniffing. Let us imagine a page composed of boxes of information; each box is about a different feline breed or canine breed. Each box has an image, an overview, and a historical funfact. The pictures are kept to a maximum reasonable size even on large screens. For the purposes of grouping the content meaningfully, all the cat boxes are separated from all the dog boxes such that the cat and dog boxes are not intermixed together. On a large screen, it saves space to have multiple columns to reduce the space wasted to the left and to the right of the pictures. The boxes can be separated into multiple columns via two equally fair method. From this point on, we shall assume that all the dog boxes are at the top of the source code, that all the cat boxes are at the bottom of the source code, and that all these boxes have the same parent element. There a single instance of a dog box immediately above a cat box, of course. The first method uses horizontal Flexboxes to group the content such that when the page is displayed to the end user, all the dogs boxes are at the top of the page and all the cat boxes are lower on the page. The second method uses a Column layout and resents all the dogs to the left and all the cats to the right. Only in this particular scenario, it is appropriate to provide no fallback for the flexboxes/multicolumns, resulting in a single column of very wide boxes on old browsers. Also consider the following. If more people visit the webpage to see the cats, then it might be a good idea to put all the cats higher in the source code than the dogs so that more people can find what they are looking for faster on smaller screens where the content collapses down to one column.
-Next, always make your code dynamic. The user can flip their mobile device on its side, changing the width and height of the page. Or, there might be some weird flip-phone-like device thing in the future where flipping it out extends the screen. Do not be the developer having a headache over how to deal with the flip-phone-like device thing. Never be satisfied with your webpage until you can open up the dev tools side panel and resize the screen while the webpage looks smooth, fluid, and dynamically resized. The simplest way to do this is to separate all the code that moves content around based on screen size to a single function that is called when the page is loaded and at each resize event thereafter. If there is a lot calculated by this layout function before it determines the new layout of the page, then consider debouncing the event listener such that it is not called as often. Also note that there is a huge difference between the media queries (max-width: 25em)
, not all and (min-width: 25em)
, and (max-width: 24.99em)
: (max-width: 25em)
excludes (max-width: 25em)
, whereas not all and (min-width: 25em)
includes (max-width: 25em)
. (max-width: 24.99em)
is a poor man's version of not all and (min-width: 25em)
: do not use (max-width: 24.99em)
because the layout might break on very high font sizes on very high definition devices in the future. Always be very deliberate about choosing the right media query and choosing the right >=, <=, >, or < in any corresponding JavaScript because it is very easy to get these mixed up, resulting in the website looking wonking right at the screen size where the layout changes. Thus, thoroughly test the website at the exact widths/heights where layout changes occur to ensure that the layout changes occur properly.
After reviewing all of the above better alternatives to user agent sniffing, there are still some potential cases where user agent sniffing is appropriate and justified.
- -One such case is using user agent sniffing as a fallback when detecting if the device has a touch screen. See the Mobile Device Detection section for more information.
- -Another such case is for fixing bugs in browsers that do not automatically update. Internet Explorer (on Windows) and Webkit (on iOS) are two perfect examples. Prior to version 9, Internet Explorer had issues with rendering bugs, CSS bugs, API bugs, and so forth. However, prior to version 9, Internet Explorer was was very easy to detect based upon the browser-specific features available. Webkit is a bit worse because Apple forces all of the browsers on IOS to use Webkit internally, thus the user has no way to get a better more updated browser on older devices. Most bugs can be detected, but some bugs take more effort to detect than others. In such cases, it might be beneficial to use user agent sniffing to save on performance. For example, Webkit 6 has a bug whereby when the device orientation changes, the browser might not fire MediaQueryList listeners when it should. To overcome this bug, observe the code below.
- -var UA=navigator.userAgent, isWebkit=/\b(iPad|iPhone|iPod)\b/.test(UA) && - /WebKit/.test(UA) && !/Edge/.test(UA) && !window.MSStream; - -var mediaQueryUpdated = true, mqL = []; -function whenMediaChanges(){mediaQueryUpdated = true} - -var listenToMediaQuery = isWebkit ? function(mQ, f) { - if(/height|width/.test(mQ.media)) mqL.push([mQ, f]); - mQ.addListener(f), mQ.addListener(whenMediaChanges); -} : function(){}; -var destroyMediaQuery = isWebkit ? function(mQ) { - for (var i=0,len=mqL.length|0; i<len; i=i+1|0) - if (mqL[i][0] === mQ) mqL.splice(i, 1); - mQ.removeListener(whenMediaChanges); -} : listenToMediaQuery; - -var orientationChanged = false; -addEventListener("orientationchange", function(){ - orientationChanged = true; -}, PASSIVE_LISTENER_OPTION); - -addEventListener("resize", setTimeout.bind(0,function(){ - if (orientationChanged && !mediaQueryUpdated) - for (var i=0,len=mqL.length|0; i<len; i=i+1|0) - mqL[i][1]( mqL[i][0] ); - mediaQueryUpdated = orientationChanged = false; -},0));- -
As there is no uniformity of the different part of the user agent string, this is the tricky part.
- -When people say they want "browser detection", often they actually want "rendering engine detection". Do you actually want to detect Firefox, as opposed to SeaMonkey, or Chrome as opposed to Chromium? Or do you actually want to see if the browser is using the Gecko or the WebKit rendering engine? If this is what you need, see further down the page.
- -Most browsers set the name and version in the format BrowserName/VersionNumber, with the notable exception of Internet Explorer. But as the name is not the only information in a user agent string that is in that format, you can not discover the name of the browser, you can only check if the name you are looking for. But note that some browsers are lying: Chrome for example reports both as Chrome and Safari. So to detect Safari you have to check for the Safari string and the absence of the Chrome string, Chromium often reports itself as Chrome too or Seamonkey sometimes reports itself as Firefox.
- -Also, pay attention not to use a simple regular expression on the BrowserName, user agents also contain strings outside the Keyword/Value syntax. Safari & Chrome contain the string 'like Gecko', for instance.
- -Engine | -Must contain | -Must not contain | -
---|---|---|
Firefox | -Firefox/xyz |
- Seamonkey/xyz |
-
Seamonkey | -Seamonkey/xyz |
- - |
Chrome | -Chrome/xyz |
- Chromium/xyz |
-
Chromium | -Chromium/xyz |
- - |
Safari | -Safari/xyz |
- Chrome/xyz or Chromium/xyz |
-
Opera 15+ (Blink-based engine) | -OPR/xyz |
- - |
Opera 12- (Presto-based engine) | -Opera/xyz |
- - |
Internet Explorer 10- | -; MSIE xyz; |
- - |
Internet Explorer 11 | -Trident/7.0; .*rv:xyz |
- - |
[1] Safari gives two version numbers: one technical in the Safari/xyz
token, and one user-friendly in a Version/xyz
token.
Of course, there is absolutely no guarantee that another browser will not hijack some of these things (like Chrome hijacked the Safari string in the past). That's why browser detection using the user agent string is unreliable and should be done only with the check of the version number (hijacking of past versions is less likely).
- -The browser version is often, but not always, put in the value part of the BrowserName/VersionNumber token in the User Agent String. This is of course not the case for Internet Explorer (which puts the version number right after the MSIE token), and for Opera after version 10, which has added a Version/VersionNumber token.
- -Here again, be sure to take the right token for the browser you are looking for, as there is no guarantee that others will contain a valid number.
- -As seen earlier, in most cases, looking for the rendering engine is a better way to go. This will help to not exclude lesser known browsers. Browsers sharing a common rendering engine will display a page in the same way: it is often a fair assumption that what will work in one will work in the other.
- -There are five major rendering engines: Trident, Gecko, Presto, Blink, and WebKit. As sniffing the rendering engines names is common, a lot of user agents added other rendering names to trigger detection. It is therefore important to pay attention not to trigger false-positives when detecting the rendering engine.
- -Engine | -Must contain | -Comment | -
---|---|---|
Gecko | -Gecko/xyz |
- - |
WebKit | -AppleWebKit/xyz |
- Pay attention, WebKit browsers add a 'like Gecko' string that may trigger false positive for Gecko if the detection is not careful. | -
Presto | -Opera/xyz |
- Note: Presto is no longer used in Opera browser builds >= version 15 (see 'Blink') | -
Trident | -Trident/xyz |
- Internet Explorer put this token in the comment part of the User Agent String | -
EdgeHTML | -Edge/xyz |
- The non-Chromium Edge puts its engine version after the Edge/ token, not the application version. - Note: EdgeHTML is no longer used in Edge browser builds >= version 79 (see 'Blink'). |
-
Blink | -Chrome/xyz |
- - |
Most rendering engines put the version number in the RenderingEngine/VersionNumber token, with the notable exception of Gecko. Gecko puts the Gecko version number in the comment part of the User Agent after the rv:
string. From Gecko 14 for the mobile version and Gecko 17 for the desktop version, it also puts this value in the Gecko/version
token (previous version put there the build date, then a fixed date called the GeckoTrail).
The Operating System is given in most User Agent strings (although not web-focused platforms like Firefox OS), but the format varies a lot. It is a fixed string between two semi-colons, in the comment part of the User Agent. These strings are specific for each browser. They indicate the OS, but also often its version and information on the relying hardware (32 or 64 bits, or Intel/PPC for Mac).
- -Like in all cases, these strings may change in the future, one should use them only in conjunction with the detection of already released browsers. A technological survey must be in place to adapt the script when new browser versions are coming out.
- -The most common reason to perform user agent sniffing is to determine which type of device the browser runs on. The goal is to serve different HTML to different device types.
- -The following table summarizes the way common browser vendors indicate that their browsers are running on a mobile device:
- -Browser | -Rule | -Example | -
---|---|---|
Mozilla (Gecko, Firefox) | -Mobile or Tablet inside the comment. |
- Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0 |
-
WebKit-based (Android, Safari) | -Mobile Safari token outside the comment. |
- Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 |
-
Blink-based (Chromium, Google Chrome, Opera 15+, Edge on Android) | -Mobile Safari token outside the comment. |
- Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047 |
-
Presto-based (Opera 12-) | -Opera Mobi/xyz token inside the comment. |
- Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50 |
-
Internet Explorer | -IEMobile/xyz token in the comment. |
- Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0) |
-
Edge on Windows 10 Mobile | -Mobile/xyz and Edge/ tokens outside the comment. |
- Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Mobile Safari/537.36 Edge/16.16299 |
-
In summary, we recommend looking for the string Mobi
anywhere in the User Agent to detect a mobile device.
Note: If the device is large enough that it's not marked with Mobi
, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).
The performance of web sites and applications can be significantly improved by reusing previously fetched resources. Web caches reduce latency and network traffic and thus lessen the time needed to display a representation of a resource. By making use of HTTP caching, Web sites become more responsive.
- -Caching is a technique that stores a copy of a given resource and serves it back when requested. When a web cache has a requested resource in its store, it intercepts the request and returns its copy instead of re-downloading from the originating server. This achieves several goals: it eases the load of the server that doesn’t need to serve all clients itself, and it improves performance by being closer to the client, i.e., it takes less time to transmit the resource back. For a web site, it is a major component in achieving high performance. On the other side, it has to be configured properly as not all resources stay identical forever: it is important to cache a resource only until it changes, not longer.
- -There are several kinds of caches: these can be grouped into two main categories: private or shared caches. A shared cache is a cache that stores responses for reuse by more than one user. A private cache is dedicated to a single user. This page will mostly talk about browser and proxy caches, but there are also gateway caches, CDN, reverse proxy caches and load balancers that are deployed on web servers for better reliability, performance and scaling of web sites and web applications.
- -A private cache is dedicated to a single user. You might have seen "caching" in your browser's settings already. A browser cache holds all documents downloaded via HTTP by the user. This cache is used to make visited documents available for back/forward navigation, saving, viewing-as-source, etc. without requiring an additional trip to the server. It likewise improves offline browsing of cached content.
- -A shared cache is a cache that stores responses to be reused by more than one user. For example, an ISP or your company might have set up a web proxy as part of its local network infrastructure to serve many users so that popular resources are reused a number of times, reducing network traffic and latency.
- -HTTP caching is optional but usually desirable. HTTP caches are typically limited to caching responses to {{HTTPMethod("GET")}}; they may decline other methods. The primary cache key consists of the request method and target URI (often only the URI is used — this is because only GET
requests are caching targets).
Common forms of caching entries are:
- -A cache entry might also consist of multiple stored responses differentiated by a secondary key, if the request is target of content negotiation. For more details see the information about the {{HTTPHeader("Vary")}} header below.
- -Cache-Control
headerThe {{HTTPHeader("Cache-Control")}} HTTP/1.1 general-header field is used to specify directives for caching mechanisms in both requests and responses. Use this header to define your caching policies with the variety of directives it provides.
- -The cache should not store anything about the client request or server response. A request is sent to the server and a full response is downloaded each and every time.
- -Cache-Control: no-store- -
A cache will send the request to the origin server for validation before releasing a cached copy.
- -Cache-Control: no-cache- -
The "public" directive indicates that the response may be cached by any cache. This can be useful if pages with HTTP authentication, or response status codes that aren't normally cacheable, should now be cached.
- -On the other hand, "private" indicates that the response is intended for a single user only and must not be stored by a shared cache. A private browser cache may store the response in this case.
- -Cache-Control: private -Cache-Control: public -- -
The most important directive here is max-age=<seconds>
, which is the maximum amount of time in which a resource will be considered fresh. This directive is relative to the time of the request, and overrides the {{HTTPHeader("Expires")}} header (if set). For the files in the application that will not change, you can normally use aggressive caching. This includes static files such as images, CSS files, and JavaScript files, for example.
For more details, see also the Freshness section below.
- -Cache-Control: max-age=31536000- -
When using the "must-revalidate
" directive, the cache must verify the status of the stale resources before using it and expired ones should not be used. For more details, see the Validation section below.
Cache-Control: must-revalidate- -
Pragma
header{{HTTPHeader("Pragma")}} is an HTTP/1.0 header. Pragma: no-cache
is like Cache-Control: no-cache
in that it forces caches to submit the request to the origin server for validation, before releasing a cached copy. However, Pragma
is not specified for HTTP responses and is therefore not a reliable replacement for the general HTTP/1.1 Cache-Control
header.
Pragma
should only be used for backwards compatibility with HTTP/1.0 caches where the Cache-Control
HTTP/1.1 header is not yet present.
Once a resource is stored in a cache, it could theoretically be served by the cache forever. Caches have finite storage so items are periodically removed from storage. This process is called cache eviction. On the other side, some resources may change on the server so the cache should be updated. As HTTP is a client-server protocol, servers can't contact caches and clients when a resource changes; they have to communicate an expiration time for the resource. Before this expiration time, the resource is fresh; after the expiration time, the resource is stale. Eviction algorithms often privilege fresh resources over stale resources. Note that a stale resource is not evicted or ignored; when the cache receives a request for a stale resource, it forwards this request with a {{HTTPHeader("If-None-Match")}} to check if it is in fact still fresh. If so, the server returns a {{HTTPStatus("304")}} (Not Modified) header without sending the body of the requested resource, saving some bandwidth.
- -Here is an example of this process with a shared cache proxy:
- -The freshness lifetime is calculated based on several headers. If a "Cache-Control: max-age=N
" header is specified, then the freshness lifetime is equal to N. If this header is not present, which is very often the case, it is checked if an {{HTTPHeader("Expires")}} header is present. If an Expires
header exists, then its value minus the value of the {{HTTPHeader("Date")}} header determines the freshness lifetime.
If an origin server does not explicitly specify freshness (e.g. using {{HTTPHeader("Cache-Control")}} or {{HTTPHeader("Expires")}} header) then a heuristic approach may be used.
- -In this case look for a {{HTTPHeader("Last-Modified")}} header. If this header is present, then the cache's freshness lifetime is equal to the value of the Date
header minus the value of the Last-modified
header divided by 10. The expiration time is computed as follows:
expirationTime = responseTime + freshnessLifetime - currentAge- -
where responseTime
is the time at which the response was received according to the browser. For more information see RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): 4.2.2. Calculating Heuristic Freshness.
The more we use cached resources, the better the responsiveness and the performance of a Web site will be. To optimize this, good practices recommend to set expiration times as far in the future as possible. This is possible on resources that are regularly updated, or often, but is problematic for resources that are rarely and infrequently updated. They are the resources that would benefit the most from caching resources, yet this makes them very difficult to update. This is typical of the technical resources included and linked from each Web pages: JavaScript and CSS files change infrequently, but when they change you want them to be updated quickly.
- -Web developers invented a technique that Steve Souders called revving. Infrequently updated files are named in a specific way: in their URL, usually in the filename, a revision (or version) number is added. That way each new revision of this resource is considered as a resource on its own that never changes and that can have an expiration time very far in the future, usually one year or even more. In order to have the new versions, all the links to them must be changed, that is the drawback of this method: additional complexity that is usually taken care of by the tool chain used by Web developers. When the infrequently variable resources change they induce an additional change to often variable resources. When these are read, the new versions of the others are also read.
- -This technique has an additional benefit: updating two cached resources at the same time will not lead to the situation where the out-dated version of one resource is used in combination with the new version of the other one. This is very important when web sites have CSS stylesheets or JS scripts that have mutual dependencies, i.e., they depend on each other because they refer to the same HTML elements.
- -The revision version added to revved resources doesn't need to be a classical revision string like 1.1.3, or even a monotonously growing suite of number. It can be anything that prevent collisions, like a hash or a date.
- -When a cached document's expiration time has been reached, it is either validated or fetched again. Validation can only occur if the server provided either a strong validator or a weak validator.
- -Revalidation is triggered when the user presses the reload button. It is also triggered under normal browsing if the cached response includes the "Cache-Control: must-revalidate
" header. Another factor is the cache validation preferences in the Advanced->Cache
preferences panel. There is an option to force a validation each time a document is loaded.
The {{HTTPHeader("ETag")}} response header is an opaque-to-the-useragent value that can be used as a strong validator. That means that a HTTP user-agent, such as the browser, does not know what this string represents and can't predict what its value would be. If the ETag
header was part of the response for a resource, the client can issue an {{HTTPHeader("If-None-Match")}} in the header of future requests – in order to validate the cached resource.
The {{HTTPHeader("Last-Modified")}} response header can be used as a weak validator. It is considered weak because it only has 1-second resolution. If the Last-Modified
header is present in a response, then the client can issue an {{HTTPHeader("If-Modified-Since")}} request header to validate the cached document.
When a validation request is made, the server can either ignore the validation request and respond with a normal {{HTTPStatus(200)}} OK
, or it can return {{HTTPStatus(304)}} Not Modified
(with an empty body) to instruct the browser to use its cached copy. The latter response can also include headers that update the expiration time of the cached document.
The {{HTTPHeader("Vary")}} HTTP response header determines how to match future request headers to decide whether a cached response can be used, or if a fresh one must be requested from the origin server.
- -When a cache receives a request that has a Vary
header field, it must not use a cached response by default unless all header fields specified in the Vary
header match in both the original (cached) request and the new request.
This feature is commonly used to allow a resource to be cached in uncompressed and (various) compressed forms, and served appropriately to user agents based on the encodings that they support. For example, a server can set
Vary: Accept-Encoding
to ensure that a separate version of a resource is cached for all requests that specify support for a particular set of encodings, e.g. Accept-Encoding: gzip,deflate,sdch
.
Vary: Accept-Encoding- -
Note: Use Vary
with care—it can easily reduce the effectiveness of caching! A caching server should use normalization to reduce duplicated cache entries and unnecessary requests to the origin server. This is particularly true when using Vary
with headers and header values that can have many values.
The Vary
header can also be useful for serving different content to desktop and mobile users, or to allow search engines to discover the mobile version of a page (and perhaps also tell them that no Cloaking is intended). This is usually achieved with the Vary: User-Agent
header, and works because the {{HTTPHeader("User-Agent")}} header value is different for mobile and desktop clients.
Vary: User-Agent- -
As discussed above, caching servers will by default match future requests only to requests with exactly the same headers and header values. That means a request will be made to the origin and a new cache will be created for every slight variant that might be specified by different user-agents.
- -For example, by default all of the following result in a separate request to the origin and a separate cache entry: Accept-Encoding: gzip,deflate,sdch
, Accept-Encoding: gzip,deflate
, Accept-Encoding: gzip
. This is true even though the origin server will probably respond with — and store — the same resource for all requests (a gzip)!
To avoid unnecessary requests and duplicated cache entries, caching servers should use normalization to pre-process the request and cache only files that are needed. For example, in the case of Accept-Encoding
you could check for gzip
and other compression types in the header before doing further processing, and otherwise unset the header. In "pseudo code" this might look like:
// Normalize Accept-Encoding -if (req.http.Accept-Encoding) { - if (req.http.Accept-Encoding ~ "gzip") { - set req.http.Accept-Encoding = "gzip"; - } - // elsif other encoding types to check - else { - unset req.http.Accept-Encoding; - } -} -- -
User-Agent
has even more variation than Accept-Encoding
. So if using Vary: User-Agent
for caching mobile/desktop variants of files you'd similarly check for the presence of "mobile"
and "desktop"
in the request User-Agent
header, and then clear it.
Compression is an important way to increase the performance of a Web site. For some documents, size reduction of up to 70% lowers the bandwidth capacity needs. Over the years, algorithms also got more efficient, and new ones are supported by clients and servers.
- -In practice, web developers don't need to implement compression mechanisms, both browsers and servers have it implemented already, but they have to be sure that the server is configured adequately. Compression happens at three different levels:
- -Each data type has some redundancy, that is wasted space, in it. If text can typically have as much as 60% redundancy, this rate can be much higher for some other media like audio and video. Unlike text, these other media types use lot of space to store their data and the need to optimize storage and regain space was apparent very early. Engineers designed the optimized compression algorithm used by file formats designed for this specific purpose. Compression algorithms used for files can be grouped into two broad categories:
- -gif
or png
are using loss-less compression.jpeg
image format is also lossy.Some formats can be used for both loss-less or lossy compression, like webp
, and usually lossy algorithm can be configured to compress more or less, which then of course leads to less or more quality. For better performance of a Web site, it is ideal to compress as much as possible, while keeping an acceptable level of quality. For images, an image generated by a tool could be not optimized enough for the Web; it is recommended to use tools that will compress as much as possible with the required quality. There are numerous tools that are specialized for this.
Lossy compression algorithms are usually more efficient than loss-less ones.
- -Note: As compression works better on a specific kind of files, it usually provides nothing to compress them a second time. In fact, this is often counter productive as the cost of the overhead (algorithms usually need a dictionary that add to the initial size) can be higher than the extra gain in compression resulting in a larger file. Do not use the two following techniques for files in a compressed format.
-For compression, end-to-end compression is where the largest performance improvements of Web sites reside. End-to-end compression refers to a compression of the body of a message that is done by the server and will last unchanged until it reaches the client. Whatever the intermediate nodes are, they leave the body untouched.
- -All modern browsers and servers do support it and the only thing to negotiate is the compression algorithm to use. These algorithm are optimized for text. In the 1990s, compression technology was advancing at a rapid pace and numerous successive algorithms have been added to the set of possible choices. Nowadays, only two are relevant: gzip
, the most common one, and br
the new challenger.
To select the algorithm to use, browsers and servers use proactive content negotiation. The browser sends an {{HTTPHeader("Accept-Encoding")}} header with the algorithm it supports and its order of precedence, the server picks one, uses it to compress the body of the response and uses the {{HTTPHeader("Content-Encoding")}} header to tell the browser the algorithm it has chosen. As content negotiation has been used to choose a representation based on its encoding, the server must send a {{HTTPHeader("Vary")}} header containing at least {{HTTPHeader("Accept-Encoding")}} alongside this header in the response; that way, caches will be able to cache the different representations of the resource.
- -As compression brings significant performance improvements, it is recommended to activate it for all files, but already compressed ones like images, audio files and videos.
- -Apache supports compression and uses mod_deflate; for nginx there is ngx_http_gzip_module; for IIS, the <httpCompression>
element.
Hop-by-hop compression, though similar to end-to-end compression, differs by one fundamental element: the compression doesn't happen on the resource in the server, creating a specific representation that is then transmitted, but on the body of the message between any two nodes on the path between the client and the server. Connections between successive intermediate nodes may apply a different compression.
- -To do this, HTTP uses a mechanism similar to the content negotiation for end-to-end compression: the node transmitting the request advertizes its will using the {{HTTPHeader("TE")}} header and the other node chooses the adequate method, applies it, and indicates its choice with the {{HTTPHeader("Transfer-Encoding")}} header.
- -In practice, hop-by-hop compression is transparent for the server and the client, and is rarely used. {{HTTPHeader("TE")}} and {{HTTPHeader("Transfer-Encoding")}} are mostly used to send a response by chunks, allowing to start transmitting a resource without knowing its length.
- -Note that using {{HTTPHeader("Transfer-Encoding")}} and compression at the hop level is so rare that most servers, like Apache, nginx, or IIS, have no easy way to configure it. Such configuration usually happens at the proxy level.
diff --git a/files/en-us/web/http/compression/index.md b/files/en-us/web/http/compression/index.md new file mode 100644 index 000000000000000..d435db09ebedb1f --- /dev/null +++ b/files/en-us/web/http/compression/index.md @@ -0,0 +1,62 @@ +--- +title: Compression in HTTP +slug: Web/HTTP/Compression +tags: + - Guide + - HTTP + - compression +--- +{{HTTPSidebar}} + +**Compression** is an important way to increase the performance of a Web site. For some documents, size reduction of up to 70% lowers the bandwidth capacity needs. Over the years, algorithms also got more efficient, and new ones are supported by clients and servers. + +In practice, web developers don't need to implement compression mechanisms, both browsers and servers have it implemented already, but they have to be sure that the server is configured adequately. Compression happens at three different levels: + +- first some file formats are compressed with specific optimized methods, +- then general encryption can happen at the HTTP level (the resource is transmitted compressed from end to end), +- and finally compression can be defined at the connection level, between two nodes of an HTTP connection. + +## File format compression + +Each data type has some redundancy, that is _wasted space_, in it. If text can typically have as much as 60% redundancy, this rate can be much higher for some other media like audio and video. Unlike text, these other media types use lot of space to store their data and the need to optimize storage and regain space was apparent very early. Engineers designed the optimized compression algorithm used by file formats designed for this specific purpose. Compression algorithms used for files can be grouped into two broad categories: + +- _Loss-less compression_, where the compression-uncompression cycle doesn't alter the data that is recovered. It matches (byte to byte) with the original. + For images, `gif` or `png` are using loss-less compression. +- _Lossy compression_, where the cycle alters the original data in a (hopefully) imperceptible way for the user. + Video formats on the Web are lossy; the `jpeg` image format is also lossy. + +Some formats can be used for both loss-less or lossy compression, like `webp`, and usually lossy algorithm can be configured to compress more or less, which then of course leads to less or more quality. For better performance of a Web site, it is ideal to compress as much as possible, while keeping an acceptable level of quality. For images, an image generated by a tool could be not optimized enough for the Web; it is recommended to use tools that will compress as much as possible with the required quality. There are [numerous tools](https://www.creativebloq.com/design/image-compression-tools-1132865) that are specialized for this. + +Lossy compression algorithms are usually more efficient than loss-less ones. + +> **Note:** As compression works better on a specific kind of files, it usually provides nothing to compress them a second time. In fact, this is often counter productive as the cost of the overhead (algorithms usually need a dictionary that add to the initial size) can be higher than the extra gain in compression resulting in a larger file. Do not use the two following techniques for files in a compressed format. + +## End-to-end compression + +For compression, end-to-end compression is where the largest performance improvements of Web sites reside. End-to-end compression refers to a compression of the body of a message that is done by the server and will last unchanged until it reaches the client. Whatever the intermediate nodes are, they leave the body untouched. + + + +All modern browsers and servers do support it and the only thing to negotiate is the compression algorithm to use. These algorithm are optimized for text. In the 1990s, compression technology was advancing at a rapid pace and numerous successive algorithms have been added to the set of possible choices. Nowadays, only two are relevant: `gzip`, the most common one, and `br` the new challenger. + +To select the algorithm to use, browsers and servers use [proactive content negotiation](/en-US/docs/Web/HTTP/Content_negotiation). The browser sends an {{HTTPHeader("Accept-Encoding")}} header with the algorithm it supports and its order of precedence, the server picks one, uses it to compress the body of the response and uses the {{HTTPHeader("Content-Encoding")}} header to tell the browser the algorithm it has chosen. As content negotiation has been used to choose a representation based on its encoding, the server must send a {{HTTPHeader("Vary")}} header containing at least {{HTTPHeader("Accept-Encoding")}} alongside this header in the response; that way, caches will be able to cache the different representations of the resource. + + + +As compression brings significant performance improvements, it is recommended to activate it for all files, but already compressed ones like images, audio files and videos. + +Apache supports compression and uses [mod_deflate](https://httpd.apache.org/docs/current/mod/mod_deflate.html); for nginx there is [ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html); for IIS, the [`{{HTTPSidebar}}
- -HTTP has a concept of conditional requests, where the result, and even the success of a request, can be changed by comparing the affected resources with the value of a validator. Such requests can be useful to validate the content of a cache, and sparing a useless control, to verify the integrity of a document, like when resuming a download, or when preventing to lose updates when uploading or modifying a document on the server.
- -HTTP conditional requests are requests that are executed differently, depending on the value of specific headers. These headers define a precondition, and the result of the request will be different if the precondition is matched or not.
- -The different behaviors are defined by the method of the request used, and by the set of headers used for a precondition:
- -All conditional headers try to check if the resource stored on the server matches a specific version. To achieve this, the conditional requests need to indicate the version of the resource. As comparing the whole resource byte to byte is impracticable, and not always what is wanted, the request transmits a value describing the version. Such values are called validators, and are of two kinds:
- -Comparing versions of the same resource is a bit tricky: depending on the context, there are two kinds of equality checks:
- -The kind of validation is independent of the validator used. Both {{HTTPHeader("Last-Modified")}} and {{HTTPHeader("ETag")}} allow both types of validation, though the complexity to implement it on the server side may vary. HTTP uses strong validation by default, and it specifies when weak validation can be used.
- -Strong validation consists of guaranteeing that the resource is, byte to byte, identical to the one it is compared too. This is mandatory for some conditional headers, and the default for the others. Strong validation is very strict and may be difficult to guarantee at the server level, but it does guarantee no data loss at any time, sometimes at the expense of performance.
- -It is quite difficult to have a unique identifier for strong validation with {{HTTPHeader("Last-Modified")}}. Often this is done using an {{HTTPHeader("ETag")}} with the MD5 hash of the resource (or a derivative).
- -Weak validation differs from strong validation, as it considers two versions of the document as identical if the content is equivalent. For example, a page that would differ from another only by a different date in its footer, or different advertising, would be considered identical to the other with weak validation. These same two versions are considered different when using strong validation. Building a system of etags that creates weak validation may be complex, as it involves knowing the importance of the different elements of a page, but is very useful towards optimizing cache performance.
- -Several HTTP headers, called conditional headers, lead to conditional requests. These are:
- -'W/'
, it performs a strong validation.'W/'
, it performs a strong validation.Partial Content
response, a {{HTTPStatus("200")}} OK
is sent with the complete resource.The most common use case for conditional requests is updating a cache. With an empty cache, or without a cache, the requested resource is sent back with a status of {{HTTPStatus("200")}} OK
.
Together with the resource, the validators are sent in the headers. In this example, both {{HTTPHeader("Last-Modified")}} and {{HTTPHeader("ETag")}} are sent, but it could equally have been only one of them. These validators are cached with the resource (like all headers) and will be used to craft conditional requests, once the cache becomes stale.
- -As long as the cache is not stale, no requests are issued at all. But once it has become stale, this is mostly controlled by the {{HTTPHeader("Cache-Control")}} header, the client doesn't use the cached value directly but issues a conditional request. The value of the validator is used as a parameter of the {{HTTPHeader("If-Modified-Since")}} and {{HTTPHeader("If-Match")}} headers.
- -If the resource has not changed, the server sends back a {{HTTPStatus("304")}} Not Modified
response. This makes the cache fresh again, and the client uses the cached resource. Although there is a response/request round-trip that consumes some resources, this is more efficient than to transmit the whole resource over the wire again.
If the resource has changed, the server just sends back a {{HTTPStatus("200")}} OK
response, with the new version of the resource, like if the request wasn't conditional and the client uses this new resource (and caches it).
Besides the setting of the validators on the server side, this mechanism is transparent: all browsers manage a cache and send such conditional requests without any special work to be done by Web developers.
- -Partial downloading of files is a functionality of HTTP that allows to resume previous operations, saving bandwidth and time, by keeping the already obtained information:
- -A server supporting partial downloads broadcasts this by sending the {{HTTPHeader("Accept-Ranges")}} header. Once this happens, the client can resume a download by sending a {{HTTPHeader("Ranges")}} header with the missing ranges:
- -The principle is simple, but there is one potential problem: if the downloaded resource has been modified between both downloads, the obtained ranges will correspond to two different versions of the resource, and the final document will be corrupted.
- -To prevent this, conditional requests are used. For ranges, there are two ways of doing this. The more flexible one makes use of {{HTTPHeader("If-Unmodified-Since")}} and {{HTTPHeader("If-Match")}} and the server returns an error if the precondition fails; the client then restarts the download from the beginning:
- -Even if this method works, it adds an extra response/request exchange when the document has been changed. This impairs performance, and HTTP has a specific header to avoid this scenario: {{HTTPHeader("If-Range")}}:
- -This solution is more efficient, but slightly less flexible, as only one etag can be used in the condition. Rarely is such additional flexibility needed.
- -A common operation in Web applications is to update a remote document. This is very common in any file system or source control applications, but any application that allows to store remote resources needs such a mechanism. Common Web sites, like wikis and other CMS, have such a need.
- -With the {{HTTPMethod("PUT")}} method you are able to implement this. The client first reads the original files, modifies them, and finally pushes them to the server:
- -Unfortunately, things get a little inaccurate as soon as we take into account concurrency. While a client is locally modifying its new copy of the resource, a second client can fetch the same resource and do the same on its copy. What happens next is very unfortunate: when they commit back to the server, the modifications from the first client are discarded by the next client push, as this second client is unaware of the first client's changes to the resource. The decision on who wins, is not communicated to the other party. Which client's changes are to be kept, will vary with the speed they commit; this depends on the performance of the clients, of the server, and even of the human editing the document at the client. The winner will change from one time to the next. This is a {{glossary("race condition")}} and leads to problematic behaviors, which are difficult to detect and to debug:
- -There is no way to deal with this problem without annoying one of the two clients. However, lost updates and race conditions are to be avoided. We want predictable results, and expect that the clients are notified when their changes are rejected.
- -Conditional requests allow implementing the optimistic locking algorithm (used by most wikis or source control systems). The concept is to allow all clients to get copies of the resource, then let them modify it locally, controlling concurrency by successfully allowing the first client submitting an update. All subsequent updates, based on the now obsolete version of the resource, are rejected:
- -This is implemented using the {{HTTPHeader("If-Match")}} or {{HTTPHeader("If-Unmodified-Since")}} headers. If the etag doesn't match the original file, or if the file has been modified since it has been obtained, the change is rejected with a {{HTTPStatus("412")}} Precondition Failed
error. It is then up to the client to deal with the error: either by notifying the user to start again (this time on the newest version), or by showing the user a diff of both versions, helping them decide which changes they wish to keep.
The first upload of a resource is an edge case of the previous. Like any update of a resource, it is subject to a race condition if two clients try to perform at the similar times. To prevent this, conditional requests can be used: by adding {{HTTPHeader("If-None-Match")}} with the special value of '*'
, representing any etag. The request will succeed, only if the resource didn't exist before:
If-None-Match
will only work with HTTP/1.1 (and later) compliant servers. If unsure if the server will be compliant, you need first to issue a {{HTTPMethod("HEAD")}} request to the resource to check this.
Conditional requests are a key feature of HTTP, and allow the building of efficient and complex applications. For caching or resuming downloads, the only work required for webmasters is to configure the server correctly; setting correct etags in some environments can be tricky. Once achieved, the browser will serve the expected conditional requests.
- -For locking mechanisms, it is the opposite: Web developers need to issue a request with the proper headers, while webmasters can mostly rely on the application to carry out the checks for them.
- -In both cases it's clear, conditional requests are a fundamental feature behind the Web.
diff --git a/files/en-us/web/http/conditional_requests/index.md b/files/en-us/web/http/conditional_requests/index.md new file mode 100644 index 000000000000000..b795966c3c5222c --- /dev/null +++ b/files/en-us/web/http/conditional_requests/index.md @@ -0,0 +1,139 @@ +--- +title: HTTP conditional requests +slug: Web/HTTP/Conditional_requests +tags: + - Conditional Requests + - Guide + - HTTP +--- +{{HTTPSidebar}} + +HTTP has a concept of _conditional requests_, where the result, and even the success of a request, can be changed by comparing the affected resources with the value of a _validator_. Such requests can be useful to validate the content of a cache, and sparing a useless control, to verify the integrity of a document, like when resuming a download, or when preventing to lose updates when uploading or modifying a document on the server. + +## Principles + +HTTP conditional requests are requests that are executed differently, depending on the value of specific headers. These headers define a precondition, and the result of the request will be different if the precondition is matched or not. + +The different behaviors are defined by the method of the request used, and by the set of headers used for a precondition: + +- for {{glossary("Safe/HTTP", "safe")}} methods, like {{HTTPMethod("GET")}}, which usually tries to fetch a document, the conditional request can be used to send back the document, if relevant only. Therefore, this spares bandwidth. +- for {{glossary("Safe/HTTP", "unsafe")}} methods, like {{HTTPMethod("PUT")}}, which usually uploads a document, the conditional request can be used to upload the document, only if the original it is based on is the same as that stored on the server. + +## Validators + +All conditional headers try to check if the resource stored on the server matches a specific version. To achieve this, the conditional requests need to indicate the version of the resource. As comparing the whole resource byte to byte is impracticable, and not always what is wanted, the request transmits a value describing the version. Such values are called _validators_, and are of two kinds: + +- the date of last modification of the document, the _last-modified_ date. +- an opaque string, uniquely identifying each version, called the _entity tag_, or the _etag_. + +Comparing versions of the same resource is a bit tricky: depending on the context, there are two kinds of _equality checks_: + +- _Strong validation_ is used when byte to byte identity is expected, for example when resuming a download. +- _Weak validation_ is used when the user-agent only needs to determine if the two resources have the same content. This is even if they are minor differences; like different ads, or a footer with a different date. + +The kind of validation is independent of the validator used. Both {{HTTPHeader("Last-Modified")}} and {{HTTPHeader("ETag")}} allow both types of validation, though the complexity to implement it on the server side may vary. HTTP uses strong validation by default, and it specifies when weak validation can be used. + +### Strong validation + +Strong validation consists of guaranteeing that the resource is, byte to byte, identical to the one it is compared too. This is mandatory for some conditional headers, and the default for the others. Strong validation is very strict and may be difficult to guarantee at the server level, but it does guarantee no data loss at any time, sometimes at the expense of performance. + +It is quite difficult to have a unique identifier for strong validation with {{HTTPHeader("Last-Modified")}}. Often this is done using an {{HTTPHeader("ETag")}} with the MD5 hash of the resource (or a derivative). + +### Weak validation + +Weak validation differs from strong validation, as it considers two versions of the document as identical if the content is equivalent. For example, a page that would differ from another only by a different date in its footer, or different advertising, would be considered _identical_ to the other with weak validation. These same two versions are considered _different_ when using strong validation. Building a system of etags that creates weak validation may be complex, as it involves knowing the importance of the different elements of a page, but is very useful towards optimizing cache performance. + +## Conditional headers + +Several HTTP headers, called conditional headers, lead to conditional requests. These are: + +- {{HTTPHeader("If-Match")}} + - : Succeeds if the {{HTTPHeader("ETag")}} of the distant resource is equal to one listed in this header. By default, unless the etag is prefixed with `'W/'`, it performs a strong validation. +- {{HTTPHeader("If-None-Match")}} + - : Succeeds if the {{HTTPHeader("ETag")}} of the distant resource is different to each listed in this header. By default, unless the etag is prefixed with `'W/'`, it performs a strong validation. +- {{HTTPHeader("If-Modified-Since")}} + - : Succeeds if the {{HTTPHeader("Last-Modified")}} date of the distant resource is more recent than the one given in this header. +- {{HTTPHeader("If-Unmodified-Since")}} + - : Succeeds if the {{HTTPHeader("Last-Modified")}} date of the distant resource is older or the same than the one given in this header. +- {{HTTPHeader("If-Range")}} + - : Similar to {{HTTPHeader("If-Match")}}, or {{HTTPHeader("If-Unmodified-Since")}}, but can have only one single etag, or one date. If it fails, the range request fails, and instead of a {{HTTPStatus("206")}} `Partial Content` response, a {{HTTPStatus("200")}} `OK` is sent with the complete resource. + +## Use cases + +### Cache update + +The most common use case for conditional requests is updating a cache. With an empty cache, or without a cache, the requested resource is sent back with a status of {{HTTPStatus("200")}} `OK`. + + + +Together with the resource, the validators are sent in the headers. In this example, both {{HTTPHeader("Last-Modified")}} and {{HTTPHeader("ETag")}} are sent, but it could equally have been only one of them. These validators are cached with the resource (like all headers) and will be used to craft conditional requests, once the cache becomes stale. + +As long as the cache is not stale, no requests are issued at all. But once it has become stale, this is mostly controlled by the {{HTTPHeader("Cache-Control")}} header, the client doesn't use the cached value directly but issues a _conditional request_. The value of the validator is used as a parameter of the {{HTTPHeader("If-Modified-Since")}} and {{HTTPHeader("If-Match")}} headers. + +If the resource has not changed, the server sends back a {{HTTPStatus("304")}} `Not Modified` response. This makes the cache fresh again, and the client uses the cached resource. Although there is a response/request round-trip that consumes some resources, this is more efficient than to transmit the whole resource over the wire again. + + + +If the resource has changed, the server just sends back a {{HTTPStatus("200", "200 OK")}} response, with the new version of the resource, like if the request wasn't conditional and the client uses this new resource (and caches it). + + + +Besides the setting of the validators on the server side, this mechanism is transparent: all browsers manage a cache and send such conditional requests without any special work to be done by Web developers. + +### Integrity of a partial download + +Partial downloading of files is a functionality of HTTP that allows to resume previous operations, saving bandwidth and time, by keeping the already obtained information: + + + +A server supporting partial downloads broadcasts this by sending the {{HTTPHeader("Accept-Ranges")}} header. Once this happens, the client can resume a download by sending a {{HTTPHeader("Ranges")}} header with the missing ranges: + + + +The principle is simple, but there is one potential problem: if the downloaded resource has been modified between both downloads, the obtained ranges will correspond to two different versions of the resource, and the final document will be corrupted. + +To prevent this, conditional requests are used. For ranges, there are two ways of doing this. The more flexible one makes use of {{HTTPHeader("If-Unmodified-Since")}} and {{HTTPHeader("If-Match")}} and the server returns an error if the precondition fails; the client then restarts the download from the beginning: + + + +Even if this method works, it adds an extra response/request exchange when the document has been changed. This impairs performance, and HTTP has a specific header to avoid this scenario: {{HTTPHeader("If-Range")}}: + + + +This solution is more efficient, but slightly less flexible, as only one etag can be used in the condition. Rarely is such additional flexibility needed. + +### Avoiding the lost update problem with optimistic locking + +A common operation in Web applications is to _update_ a remote document. This is very common in any file system or source control applications, but any application that allows to store remote resources needs such a mechanism. Common Web sites, like wikis and other CMS, have such a need. + +With the {{HTTPMethod("PUT")}} method you are able to implement this. The client first reads the original files, modifies them, and finally pushes them to the server: + + + +Unfortunately, things get a little inaccurate as soon as we take into account concurrency. While a client is locally modifying its new copy of the resource, a second client can fetch the same resource and do the same on its copy. What happens next is very unfortunate: when they commit back to the server, the modifications from the first client are discarded by the next client push, as this second client is unaware of the first client's changes to the resource. The decision on who wins, is not communicated to the other party. Which client's changes are to be kept, will vary with the speed they commit; this depends on the performance of the clients, of the server, and even of the human editing the document at the client. The winner will change from one time to the next. This is a {{glossary("race condition")}} and leads to problematic behaviors, which are difficult to detect and to debug: + + + +There is no way to deal with this problem without annoying one of the two clients. However, lost updates and race conditions are to be avoided. We want predictable results, and expect that the clients are notified when their changes are rejected. + +Conditional requests allow implementing the _optimistic locking algorithm_ (used by most wikis or source control systems). The concept is to allow all clients to get copies of the resource, then let them modify it locally, controlling concurrency by successfully allowing the first client submitting an update. All subsequent updates, based on the now obsolete version of the resource, are rejected: + + + +This is implemented using the {{HTTPHeader("If-Match")}} or {{HTTPHeader("If-Unmodified-Since")}} headers. If the etag doesn't match the original file, or if the file has been modified since it has been obtained, the change is rejected with a {{HTTPStatus("412")}} `Precondition Failed` error. It is then up to the client to deal with the error: either by notifying the user to start again (this time on the newest version), or by showing the user a _diff_ of both versions, helping them decide which changes they wish to keep. + +### Dealing with the first upload of a resource + +The first upload of a resource is an edge case of the previous. Like any update of a resource, it is subject to a race condition if two clients try to perform at the similar times. To prevent this, conditional requests can be used: by adding {{HTTPHeader("If-None-Match")}} with the special value of `'*'`, representing any etag. The request will succeed, only if the resource didn't exist before: + + + +`If-None-Match` will only work with HTTP/1.1 (and later) compliant servers. If unsure if the server will be compliant, you need first to issue a {{HTTPMethod("HEAD")}} request to the resource to check this. + +## Conclusion + +Conditional requests are a key feature of HTTP, and allow the building of efficient and complex applications. For caching or resuming downloads, the only work required for webmasters is to configure the server correctly; setting correct etags in some environments can be tricky. Once achieved, the browser will serve the expected conditional requests. + +For locking mechanisms, it is the opposite: Web developers need to issue a request with the proper headers, while webmasters can mostly rely on the application to carry out the checks for them. + +In both cases it's clear, conditional requests are a fundamental feature behind the Web. diff --git a/files/en-us/web/http/configuring_servers_for_ogg_media/index.html b/files/en-us/web/http/configuring_servers_for_ogg_media/index.html deleted file mode 100644 index ba76d6e2af3b321..000000000000000 --- a/files/en-us/web/http/configuring_servers_for_ogg_media/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Configuring servers for Ogg media -slug: Web/HTTP/Configuring_servers_for_Ogg_media -tags: - - Audio - - HTTP - - Media - - Ogg - - Video ---- -HTML {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements allow media presentation without the need for the user to install any plug-ins or other software to do so. - This guide covers a few server configuration changes that may be necessary for your web server to correctly serve Ogg media files. - This information may also be useful if you encounter other media types your server isn't already configured to recognize.
- -*.ogg
and *.ogv
files containing video (possibly with an audio track as well, of course), should be served with the video/ogg
MIME type. *.oga
and *.ogg
files containing only audio should be served with the audio/ogg
MIME type.
If you don't know whether the Ogg file contains audio or video, you can serve it with the MIME type application/ogg
, and the browser will treat it as a video file.
Most servers don't by default serve Ogg media with the correct MIME types, so you'll likely need to add the appropriate configuration for this.
- -For Apache, you can add the following to your configuration:
- -AddType audio/ogg .oga -AddType video/ogg .ogv -AddType application/ogg .ogg -- -
You can find specific information about possible media file types and the codecs used within them in our comprehensive guide to media types and formats on the web. In particular, the article on media container formats will be especially helpful when configuring servers to host media properly.
- -In order to support seeking and playing back regions of the media that aren't yet downloaded, Gecko uses HTTP 1.1 byte-range requests to retrieve the media from the seek target position. In addition, Gecko uses byte-range requests to seek to the end of the media (assuming you serve the {{HTTPHeader("Content-Length")}} header) in order to determine the duration of the media.
- -Your server should accept the {{HTTPHeader("Accept-Ranges")}}: bytes
HTTP header if it can accept byte-range requests. It must return {{HTTPStatus("206")}}: Partial content
to all byte range requests; otherwise, browsers can't be sure you actually support byte range requests.
Your server must also return 206: Partial Content
for the request Range: bytes=0-
as well.
When the browser seeks through Ogg media to a specified time, it has to seek to the nearest key frame before the seek target, then download and decode the video from there until the requested target time. The farther apart your key frames are, the longer this takes, so it's helpful to include key frames at regular intervals.
- -By default, ffmpeg2theora
uses one key frame every 64 frames (or about every 2 seconds at 30 frames per second), which works pretty well.
Note: Of course, the more key frames you use, the larger your video file is, so you may need to experiment a bit to get the right balance between file size and seek performance.
-The HTML {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements provide the preload
attribute, which tells the browser to attempt to download the entire media when the page loads. Without preload
, the browser only downloads enough of the media to display the first video frame, and to determine the media's duration.
preload
is off by default, so if getting to video is the point of your web page, your users may appreciate it if you include preload
in your video elements. using preload="metadata"
will preload the media file's metadata and possibly the first few frames of video. Setting payload
to auto
tells the browser to automatically begin downloading the media as soon as the page is loaded, under the assumption that the user will play it.
Note: As of Firefox 41, the X-Content-Duration
header is no longer supported. See {{Bug(1160695)}} for more details.
The Ogg format doesn't encapsulate the duration of media, so for the progress bar on the video controls to display the duration of the video, Gecko needs to determine the length of the media using other means.
- -There are two ways Gecko can do this. The best way is to offer an X-Content-Duration
header when serving Ogg media files. This header provides the duration of the video in seconds (not in HH:MM:SS format) as a floating-point value.
For example, if the video is 1 minute and 32.6 seconds long, this header would be:
- -X-Content-Duration: 92.6 -- -
If your server provides the X-Content-Duration
header when serving Ogg media, Gecko doesn't have to do any extra HTTP requests to seek to the end of the file to calculate its duration. This makes the entire process much more efficient as well as more accurate.
As an inferior alternative, Gecko can estimate the video length based on the Content-Length. See next point.
- -One common way to reduce the load on a web server is to use gzip or deflate compression when serving to a supporting web browser.
- -Although it's unlikely, it's possible the browser may advertise that it supports HTTP compression (gzip/deflate) using the Accept-Encoding: gzip,deflate
header when requesting media files. Your server should be configured to not do so. The data in media files is already compressed, so you won't get any real benefit from compression, and the use of compression makes it impossible for the browser to properly seek the video or determine its duration.
Another probelm with allowing HTTP compression for media streaming: Apache servers don't send the {{HTTPHeader("Content-Length")}} response header if gzip encoding is used.
- -You can use the oggz-info
tool to get the media duration; this tool is included with the oggz-tools
package. The output from oggz-info
looks like this:
$ oggz-info /g/media/bruce_vs_ironman.ogv - Content-Duration: 00:01:00.046 - - Skeleton: serialno 1976223438 - 4 packets in 3 pages, 1.3 packets/page, 27.508% Ogg overhead - Presentation-Time: 0.000 - Basetime: 0.000 - - Theora: serialno 0170995062 - 1790 packets in 1068 pages, 1.7 packets/page, 1.049% Ogg overhead - Video-Framerate: 29.983 fps - Video-Width: 640 - Video-Height: 360 - - Vorbis: serialno 0708996688 - 4531 packets in 167 pages, 27.1 packets/page, 1.408% Ogg overhead - Audio-Samplerate: 44100 Hz - Audio-Channels: 2 -- -
Note that you can't serve up the reported Content-Duration line reported by oggz-info
, because it's reported in HH:MM:SS format. You'll need to convert it to seconds only, then serve that as your X-Content-Duration
value. Just parse out the HH, MM, and SS into numbers, then do (HH*3600)+(MM*60)+SS to get the value you should report.
It's important to note that it appears that oggz-info
makes a read pass of the media in order to calculate its duration, so it's a good idea to store the duration value in order to avoid lengthy delays while the value is calculated for every HTTP request of your Ogg media.
Connection management is a key topic in HTTP: opening and maintaining connections largely impacts the performance of Web sites and Web applications. In HTTP/1.x, there are several models: short-lived connections, persistent connections, and HTTP pipelining.
- -HTTP mostly relies on TCP for its transport protocol, providing a connection between the client and the server. In its infancy, HTTP used a single model to handle such connections. These connections were short-lived: a new one created each time a request needed sending, and closed once the answer had been received.
- -This simple model held an innate limitation on performance: opening each TCP connection is a resource-consuming operation. Several messages must be exchanged between the client and the server. Network latency and bandwidth affect performance when a request needs sending. Modern Web pages require many requests (a dozen or more) to serve the amount of information needed, proving this earlier model inefficient.
- -Two newer models were created in HTTP/1.1. The persistent-connection model keeps connections opened between successive requests, reducing the time needed to open new connections. The HTTP pipelining model goes one step further, by sending several successive requests without even waiting for an answer, reducing much of the latency in the network.
- -Note: HTTP/2 adds additional models for connection management.
-It's important point to note that connection management in HTTP applies to the connection between two consecutive nodes, which is hop-by-hop and not end-to-end. The model used in connections between a client and its first proxy may differ from the model between a proxy and the destination server (or any intermediate proxies). The HTTP headers involved in defining the connection model, like {{HTTPHeader("Connection")}} and {{HTTPHeader("Keep-Alive")}}, are hop-by-hop headers with their values able to be changed by intermediary nodes.
- -A related topic is the concept of HTTP connection upgrades, wherein an HTTP/1.1 connection is upgraded to a different protocol, such as TLS/1.0, WebSocket, or even HTTP/2 in cleartext. This protocol upgrade mechanism is documented in more detail elsewhere.
- -The original model of HTTP, and the default one in HTTP/1.0, is short-lived connections. Each HTTP request is completed on its own connection; this means a TCP handshake happens before each HTTP request, and these are serialized.
- -The TCP handshake itself is time-consuming, but a TCP connection adapts to its load, becoming more efficient with more sustained (or warm) connections. Short-lived connections do not make use of this efficiency feature of TCP, and performance degrades from optimum by persisting to transmit over a new, cold connection.
- -This model is the default model used in HTTP/1.0 (if there is no {{HTTPHeader("Connection")}} header, or if its value is set to close
). In HTTP/1.1, this model is only used when the {{HTTPHeader("Connection")}} header is sent with a value of close
.
Note: Unless dealing with a very old system, which doesn't support a persistent connection, there is no compelling reason to use this model.
-Short-lived connections have two major hitches: the time taken to establish a new connection is significant, and performance of the underlying TCP connection gets better only when this connection has been in use for some time (warm connection). To ease these problems, the concept of a persistent connection has been designed, even prior to HTTP/1.1. Alternatively this may be called a keep-alive connection.
- -A persistent connection is one which remains open for a period of time, and can be reused for several requests, saving the need for a new TCP handshake, and utilizing TCP's performance enhancing capabilities. This connection will not stay open forever: idle connections are closed after some time (a server may use the {{HTTPHeader("Keep-Alive")}} header to specify a minimum time the connection should be kept open).
- -Persistent connections also have drawbacks; even when idling they consume server resources, and under heavy load, {{glossary("DoS attack", "DoS attacks")}} can be conducted. In such cases, using non-persistent connections, which are closed as soon as they are idle, can provide better performance.
- -HTTP/1.0 connections are not persistent by default. Setting {{HTTPHeader("Connection")}} to anything other than close
, usually retry-after
, will make them persistent.
In HTTP/1.1, persistence is the default, and the header is no longer needed (but it is often added as a defensive measure against cases requiring a fallback to HTTP/1.0).
- -Note: HTTP pipelining is not activated by default in modern browsers:
-For these reasons, pipelining has been superseded by a better algorithm, multiplexing, that is used by HTTP/2.
-By default, HTTP requests are issued sequentially. The next request is only issued once the response to the current request has been received. As they are affected by network latencies and bandwidth limitations, this can result in significant delay before the next request is seen by the server.
- -Pipelining is the process to send successive requests, over the same persistent connection, without waiting for the answer. This avoids latency of the connection. Theoretically, performance could also be improved if two HTTP requests were to be packed into the same TCP message. The typical MSS (Maximum Segment Size), is big enough to contain several simple requests, although the demand in size of HTTP requests continues to grow.
- -Not all types of HTTP requests can be pipelined: only {{glossary("idempotent")}} methods, that is {{HTTPMethod("GET")}}, {{HTTPMethod("HEAD")}}, {{HTTPMethod("PUT")}} and {{HTTPMethod("DELETE")}}, can be replayed safely: should a failure happen, the pipeline content can be repeated.
- -Today, every HTTP/1.1-compliant proxy and server should support pipelining, though many have limitations in practice: a significant reason no modern browser activates this feature by default.
- -Note: Unless you have a very specific immediate need, don't use this deprecated technique; switch to HTTP/2 instead. In HTTP/2, domain sharding is no longer useful: the HTTP/2 connection is able to handle parallel unprioritized requests very well. Domain sharding is even detrimental to performance. Most HTTP/2 implementations use a technique called connection coalescing to revert eventual domain sharding.
-As an HTTP/1.x connection is serializing requests, even without any ordering, it can't be optimal without large enough available bandwidth. As a solution, browsers open several connections to each domain, sending parallel requests. Default was once 2 to 3 connections, but this has now increased to a more common use of 6 parallel connections. There is a risk of triggering DoS protection on the server side if attempting more than this number.
- -If the server wishes a faster Web site or application response, it is possible for the server to force the opening of more connections. For example, Instead of having all resources on the same domain, say www.example.com
, it could split over several domains, www1.example.com
, www2.example.com
, www3.example.com
. Each of these domains resolve to the same server, and the Web browser will open 6 connections to each (in our example, boosting the connections to 18). This technique is called domain sharding.
Improved connection management allows considerable boosting of performance in HTTP. With HTTP/1.1 or HTTP/1.0, using a persistent connection – at least until it becomes idle – leads to the best performance. However, the failure of pipelining has lead to designing superior connection management models, which have been incorporated into HTTP/2.
diff --git a/files/en-us/web/http/connection_management_in_http_1.x/index.md b/files/en-us/web/http/connection_management_in_http_1.x/index.md new file mode 100644 index 000000000000000..97dd861c7dcfcd0 --- /dev/null +++ b/files/en-us/web/http/connection_management_in_http_1.x/index.md @@ -0,0 +1,82 @@ +--- +title: Connection management in HTTP/1.x +slug: Web/HTTP/Connection_management_in_HTTP_1.x +tags: + - Connection Management + - Guide + - HTTP + - Networking + - Performance + - WebMechanics +--- +{{HTTPSidebar}} + +Connection management is a key topic in HTTP: opening and maintaining connections largely impacts the performance of Web sites and Web applications. In HTTP/1.x, there are several models: _short-lived connections_, _persistent connections_, and _HTTP pipelining._ + +HTTP mostly relies on TCP for its transport protocol, providing a connection between the client and the server. In its infancy, HTTP used a single model to handle such connections. These connections were short-lived: a new one created each time a request needed sending, and closed once the answer had been received. + +This simple model held an innate limitation on performance: opening each TCP connection is a resource-consuming operation. Several messages must be exchanged between the client and the server. Network latency and bandwidth affect performance when a request needs sending. Modern Web pages require many requests (a dozen or more) to serve the amount of information needed, proving this earlier model inefficient. + +Two newer models were created in HTTP/1.1. The persistent-connection model keeps connections opened between successive requests, reducing the time needed to open new connections. The HTTP pipelining model goes one step further, by sending several successive requests without even waiting for an answer, reducing much of the latency in the network. + + + +> **Note:** HTTP/2 adds additional models for connection management. + +It's important point to note that connection management in HTTP applies to the connection between two consecutive nodes, which is [hop-by-hop](/en-US/docs/Web/HTTP/Headers#hbh) and not [end-to-end](/en-US/docs/Web/HTTP/Headers#e2e). The model used in connections between a client and its first proxy may differ from the model between a proxy and the destination server (or any intermediate proxies). The HTTP headers involved in defining the connection model, like {{HTTPHeader("Connection")}} and {{HTTPHeader("Keep-Alive")}}, are [hop-by-hop](/en-US/docs/Web/HTTP/Headers#hbh) headers with their values able to be changed by intermediary nodes. + +A related topic is the concept of HTTP connection upgrades, wherein an HTTP/1.1 connection is upgraded to a different protocol, such as TLS/1.0, WebSocket, or even HTTP/2 in cleartext. This [protocol upgrade mechanism](/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) is documented in more detail elsewhere. + +## Short-lived connections + +The original model of HTTP, and the default one in HTTP/1.0, is _short-lived connections_. Each HTTP request is completed on its own connection; this means a TCP handshake happens before each HTTP request, and these are serialized. + +The TCP handshake itself is time-consuming, but a TCP connection adapts to its load, becoming more efficient with more sustained (or warm) connections. Short-lived connections do not make use of this efficiency feature of TCP, and performance degrades from optimum by persisting to transmit over a new, cold connection. + +This model is the default model used in HTTP/1.0 (if there is no {{HTTPHeader("Connection")}} header, or if its value is set to `close`). In HTTP/1.1, this model is only used when the {{HTTPHeader("Connection")}} header is sent with a value of `close`. + +> **Note:** Unless dealing with a very old system, which doesn't support a persistent connection, there is no compelling reason to use this model. + +## Persistent connections + +Short-lived connections have two major hitches: the time taken to establish a new connection is significant, and performance of the underlying TCP connection gets better only when this connection has been in use for some time (warm connection). To ease these problems, the concept of a _persistent connection_ has been designed, even prior to HTTP/1.1. Alternatively this may be called a _keep-alive connection_. + +A persistent connection is one which remains open for a period of time, and can be reused for several requests, saving the need for a new TCP handshake, and utilizing TCP's performance enhancing capabilities. This connection will not stay open forever: idle connections are closed after some time (a server may use the {{HTTPHeader("Keep-Alive")}} header to specify a minimum time the connection should be kept open). + +Persistent connections also have drawbacks; even when idling they consume server resources, and under heavy load, {{glossary("DoS attack", "DoS attacks")}} can be conducted. In such cases, using non-persistent connections, which are closed as soon as they are idle, can provide better performance. + +HTTP/1.0 connections are not persistent by default. Setting {{HTTPHeader("Connection")}} to anything other than `close`, usually `retry-after`, will make them persistent. + +In HTTP/1.1, persistence is the default, and the header is no longer needed (but it is often added as a defensive measure against cases requiring a fallback to HTTP/1.0). + +## HTTP pipelining + +> **Note:** HTTP pipelining is not activated by default in modern browsers: +> +> - Buggy [proxies](https://en.wikipedia.org/wiki/Proxy_server) are still common and these lead to strange and erratic behaviors that Web developers cannot foresee and diagnose easily. +> - Pipelining is complex to implement correctly: the size of the resource being transferred, the effective [RTT](https://en.wikipedia.org/wiki/Round-trip_delay_time) that will be used, as well as the effective bandwidth, have a direct incidence on the improvement provided by the pipeline. Without knowing these, important messages may be delayed behind unimportant ones. The notion of important even evolves during page layout! HTTP pipelining therefore brings a marginal improvement in most cases only. +> - Pipelining is subject to the [HOL](https://en.wikipedia.org/wiki/Head-of-line_blocking) problem. +> +> For these reasons, pipelining has been superseded by a better algorithm, _multiplexing_, that is used by HTTP/2. + +By default, [HTTP](/en-US/docs/Web/HTTP) requests are issued sequentially. The next request is only issued once the response to the current request has been received. As they are affected by network latencies and bandwidth limitations, this can result in significant delay before the next request is _seen_ by the server. + +Pipelining is the process to send successive requests, over the same persistent connection, without waiting for the answer. This avoids latency of the connection. Theoretically, performance could also be improved if two HTTP requests were to be packed into the same TCP message. The typical [MSS](https://en.wikipedia.org/wiki/Maximum_segment_size) (Maximum Segment Size), is big enough to contain several simple requests, although the demand in size of HTTP requests continues to grow. + +Not all types of HTTP requests can be pipelined: only {{glossary("idempotent")}} methods, that is {{HTTPMethod("GET")}}, {{HTTPMethod("HEAD")}}, {{HTTPMethod("PUT")}} and {{HTTPMethod("DELETE")}}, can be replayed safely: should a failure happen, the pipeline content can be repeated. + +Today, every HTTP/1.1-compliant proxy and server should support pipelining, though many have limitations in practice: a significant reason no modern browser activates this feature by default. + +## Domain sharding + +> **Note:** Unless you have a very specific immediate need, don't use this deprecated technique; switch to HTTP/2 instead. In HTTP/2, domain sharding is no longer useful: the HTTP/2 connection is able to handle parallel unprioritized requests very well. Domain sharding is even detrimental to performance. Most HTTP/2 implementations use a technique called [connection coalescing](https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/) to revert eventual domain sharding. + +As an HTTP/1.x connection is serializing requests, even without any ordering, it can't be optimal without large enough available bandwidth. As a solution, browsers open several connections to each domain, sending parallel requests. Default was once 2 to 3 connections, but this has now increased to a more common use of 6 parallel connections. There is a risk of triggering [DoS](/en-US/docs/Glossary/DOS_attack) protection on the server side if attempting more than this number. + +If the server wishes a faster Web site or application response, it is possible for the server to force the opening of more connections. For example, Instead of having all resources on the same domain, say `www.example.com`, it could split over several domains, `www1.example.com`, `www2.example.com`, `www3.example.com`. Each of these domains resolve to the _same_ server, and the Web browser will open 6 connections to each (in our example, boosting the connections to 18). This technique is called _domain sharding_. + + + +## Conclusion + +Improved connection management allows considerable boosting of performance in HTTP. With HTTP/1.1 or HTTP/1.0, using a persistent connection – at least until it becomes idle – leads to the best performance. However, the failure of pipelining has lead to designing superior connection management models, which have been incorporated into HTTP/2. diff --git a/files/en-us/web/http/content_negotiation/index.html b/files/en-us/web/http/content_negotiation/index.html deleted file mode 100644 index 07ce32beca1b735..000000000000000 --- a/files/en-us/web/http/content_negotiation/index.html +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: Content negotiation -slug: Web/HTTP/Content_negotiation -tags: - - Content Negotiation - - Content Negotiation Reference - - HTTP - - Reference ---- -In HTTP, content negotiation is the mechanism that is used for serving different representations of a resource at the same URI, so that the user agent can specify which is best suited for the user (for example, which language of a document, which image format, or which content encoding).
- -Note: Some disadvantages of HTTP content negotiation are explained in a wiki page from WHATWG. HTML5 provides alternatives to content negotiation via, for example, the <source>
element.
A specific document is called a resource. When a client wants to obtain a resource, the client requests it using its URL. The server uses this URL to choose one of the variants it provides – each variant being called a representation – and returns a specific representation to the client. The overall resource, as well as each of the representations, have a specific URL. How a specific representation is chosen when the resource is called is determined by content negotiation and there are several ways of negotiating between the client and the server.
- -The determination of the best suited representation is made through one of two mechanisms:
- -Over the years, other content negotiation proposals, like transparent content negotiation and the Alternates
header, have been proposed. They failed to get traction and got abandoned.
In server-driven content negotiation, or proactive content negotiation, the browser (or any other kind of user-agent) sends several HTTP headers along with the URL. These headers describe the preferred choice of the user. The server uses them as hints and an internal algorithm chooses the best content to serve to the client. If it cannot provide a suitable resource, as a fallback it might respond with {{HTTPStatus("406")}} (Not Acceptable) or {{HTTPStatus("415")}} (Unsupported Media Type) and set headers for the types of media that it does support (e.g. using the {{HTTPHeader("Accept-Post")}} or {{HTTPHeader("Accept-Patch")}} for POST and PATCH requests, respectively). The algorithm is server-specific and not defined in the standard. See, for example, the Apache negotiation algorithm.
- -The HTTP/1.1 standard defines list of the standard headers that start server-driven negotiation (such as {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Encoding")}}, and {{HTTPHeader("Accept-Language")}}). Though strictly speaking {{HTTPHeader("User-Agent")}} is not in this list, it is sometimes also used to send a specific representation of the requested resource, though this is not considered as a good practice. The server uses the {{HTTPHeader("Vary")}} header to indicate which headers it actually used for content negotiation (or more precisely the associated response headers), so that caches can work optimally.
- -In addition to these, there is an experimental proposal to add more headers to the list of available headers, called client hints. Client hints advertise what kind of device the user agent runs on (for example, if it is a desktop computer or a mobile device).
- -Even if server-driven content negotiation is the most common way to agree on a specific representation of a resource, it has several drawbacks:
- -The {{HTTPHeader("Accept")}} header lists the MIME types of media resources that the agent is willing to process. It is comma-separated lists of MIME types, each combined with a quality factor, a parameter indicating the relative degree of preference between the different MIME types.
- -The {{HTTPHeader("Accept")}} header is defined by the browser, or any other user-agent, and can vary according to the context, like fetching an HTML page or an image, a video, or a script: It is different when fetching a document entered in the address bar or an element linked via an {{ HTMLElement("img") }}, {{ HTMLElement("video") }} or {{ HTMLElement("audio") }} element. Browsers are free to use the value of the header that they think is the most adequate; an exhaustive list of default values for common browsers is available.
- -Note: This is part of an experimental technology called Client Hints. Initial support is in Chrome 46 or later. The Device-Memory value is in Chrome 61 or later.
-The experimental {{HTTPHeader("Accept-CH")}} lists configuration data that can be used by the server to select an appropriate response. Valid values are:
- -Value | -Meaning | -
---|---|
Device-Memory |
- Indicates the approximate amount of device RAM. This value is an approximation given by rounding to the nearest power of 2 and dividing that number by 1024. For example, 512 megabytes will be reported as 0.5 . |
-
Viewport-Width |
- Indicates the layout viewport width in CSS pixels. | -
Width |
- Indicates the resource width in physical pixels (in other words the intrinsic size of an image). | -
Note: This is part of an experimental technology called Client Hints and is only available in Chrome 61 or later.
-The {{HTTPHeader("Accept-CH-Lifetime")}} header is used with the Device-Memory
value of the Accept-CH
header and indicates the amount of time the device should opt-in to sharing the amount of device memory with the server. The value is given in milliseconds and it's use is optional.
The {{HTTPHeader("Accept-Encoding")}} header defines the acceptable content-encoding (supported compressions). The value is a q-factor list (e.g.: br, gzip;q=0.8
) that indicates the priority of the encoding values. The default value identity
is at the lowest priority (unless otherwise declared).
Compressing HTTP messages is one of the most important ways to improve the performance of a Web site, it shrinks the size of the data transmitted and makes better use of the available bandwidth; browsers always send this header and the server should be configured to abide to it and to use compression.
- -The {{HTTPHeader("Accept-Language")}} header is used to indicate the language preference of the user. It is a list of values with quality factors (like: "de, en;q=0.7
"). A default value is often set according the language of the graphical interface of the user agent, but most browsers allow to set different language preferences.
Due to the configuration-based entropy increase, a modified value can be used to fingerprint the user, it is not recommended to change it and a Web site cannot trust this value to reflect the actual wish of the user. Site designers must not be over-zealous by using language detection via this header as it can lead to a poor user experience:
- -Accept-Language
header, adapted to the user interface language and end users often do not modify it, either by not knowing how, or by not being able to do it, as in an Internet café for instance.Note: Though there are legitimate uses of this header for selecting content, it is considered bad practice to rely on it to define what features are supported by the user agent.
-The {{HTTPHeader("User-Agent")}} header identifies the browser sending the request. This string may contain a space-separated list of product tokens and comments.
- -A product token is a name followed by a '/
' and a version number, like Firefox/4.0.1
. There may be as many of them as the user-agent wants. A comment is a free string delimited by parentheses. Obviously parentheses cannot be used in that string. The inner format of a comment is not defined by the standard, though several browser put several tokens in it, separated by ';
'.
In contrast to the previous Accept-*
headers, which are sent by the client, the {{HTTPHeader("Vary")}} HTTP header is sent by the web server in its response. It indicates the list of headers used by the server during the server-driven content negotiation phase. The header is needed in order to inform the cache of the decision criteria so that it can reproduce it, allowing the cache to be functional while preventing serving erroneous content to the user.
The special value of '*
' means that the server-driven content negotiation also uses information not conveyed in a header to choose the appropriate content.
The Vary
header was added in the version 1.1 of HTTP and is necessary in order to allow caches to work appropriately. A cache, in order to work with server-driven content negotiation, needs to know which criteria was used by the server to select the transmitted content. That way, the cache can replay the algorithm and will be able to serve acceptable content directly, without more request to the server. Obviously, the wildcard '*
' prevents caching from occurring, as the cache cannot know what element is behind it. For more information HTTP caching > Varying responses.
Server-driven negotiation suffers from a few downsides: it doesn't scale well. There is one header per feature used in the negotiation. If you want to use screen size, resolution or other dimensions, a new HTTP header must be created. Sending of the headers must be done on every request. This is not too problematic with few headers, but with the eventual multiplications of them, the message size would lead to a decrease in performance. The more precise headers are sent, the more entropy is sent, allowing for more HTTP fingerprinting and corresponding privacy concern.
- -From the beginnings of HTTP, the protocol allowed another negotiation type: agent-driven negotiation or reactive negotiation. In this negotiation, when facing an ambiguous request, the server sends back a page containing links to the available alternative resources. The user is presented the resources and choose the one to use.
- -Unfortunately, the HTTP standard does not specify the format of the page for choosing between the available resource, which prevents the process being automated. Besides falling back to the server-driven negotiation, this method is almost always used in conjunction with scripting, especially with JavaScript redirection: after having checked for the negotiation criteria, the script performs the redirection. A second problem is that one more request is needed in order to fetch the real resource, slowing the availability of the resource to the user.
diff --git a/files/en-us/web/http/content_negotiation/index.md b/files/en-us/web/http/content_negotiation/index.md new file mode 100644 index 000000000000000..d6fb53a0d875d0b --- /dev/null +++ b/files/en-us/web/http/content_negotiation/index.md @@ -0,0 +1,108 @@ +--- +title: Content negotiation +slug: Web/HTTP/Content_negotiation +tags: + - Content Negotiation + - Content Negotiation Reference + - HTTP + - Reference +--- +{{HTTPSidebar}} + +In [HTTP](/en-US/docs/Glossary/HTTP), **_content negotiation_** is the mechanism that is used for serving different representations of a resource at the same URI, so that the user agent can specify which is best suited for the user (for example, which language of a document, which image format, or which content encoding). + +> **Note:** Some disadvantages of HTTP content negotiation are explained in [a wiki page from WHATWG](https://wiki.whatwg.org/wiki/Why_not_conneg). HTML5 provides alternatives to content negotiation via, for example, the [`This article documents the default values for the HTTP Accept
header for specific inputs and browser versions.
These are the values sent when the context doesn't give better information. Note that all browsers add the */*
MIME Type to cover all cases. This is typically used for requests initiated via the address bar of a browser, or via an HTML {{HTMLElement("a")}} element.
User Agent | -Value | -
---|---|
Firefox 72 and later [1] | -text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 |
-
Firefox 66 to 71 [1] | -text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
-
Firefox 65 [1] | -text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 |
-
Firefox 64 and earlier [1] | -text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
-
Safari, Chrome | -text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 |
-
Safari 5 [2] | -text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
-
Internet Explorer 8 [3] | -image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */* |
-
Edge | -text/html, application/xhtml+xml, image/jxr, */* |
-
Opera | -text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 |
-
[1] This value can be modified using the network.http.accept.default
parameter.
[2] This is an improvement over earlier Accept
headers as it no longer ranks image/png
above text/html
.
[3] See IE and the Accept Header (IEInternals' MSDN blog).
- -When requesting an image, like through an HTML {{HTMLElement("img")}} element, user-agent often sets a specific list of media types to be welcomed.
- -User Agent | -Value | -
---|---|
Firefox 65 and later [1] | -image/webp,*/* |
-
Firefox 47 to 63 [1] | -*/* |
-
Firefox prior to 47 [1] | -image/png,image/*;q=0.8,*/*;q=0.5 |
-
Safari (since Mac OS Big Sur) | -image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5 |
-
Safari (before Mac OS Big Sur) | -image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5 |
-
Chrome | -image/avif,image/webp,image/apng,image/*,*/*;q=0.8 |
-
Internet Explorer 9 | -image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5 |
-
Internet Explorer 8 or earlier source | -*/* |
-
[1] This value can be modified using the image.http.accept
parameter (source).
When a video is requested, via the {{HTMLElement("video")}} HTML element, most browsers use specific values.
- -User Agent | -Value | -
---|---|
Firefox 3.6 and later | -video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5 |
-
Firefox earlier than 3.6 | -no support for {{HTMLElement("video")}} | -
Chrome | -*/* |
-
Internet Explorer 8 or earlier | -no support for {{HTMLElement("video")}} | -
When an audio file is requested, like via the {{HTMLElement("audio")}} HTML element, most browsers use specific values.
- -User Agent | -Value | -
---|---|
Firefox 3.6 and later [1] | -audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5 |
-
Safari, Chrome | -*/* |
-
Internet Explorer 8 or earlier | -no support for {{HTMLElement("audio")}} | -
Internet Explorer 9 | -? | -
[1] See bug 489071.
- -When a script is requested, like via the {{HTMLElement("script")}} HTML element, some browsers use specific values.
- -User Agent | -Value | -
---|---|
Firefox [1] | -*/* |
-
Safari, Chrome | -*/* |
-
Internet Explorer 8 or earlier [2] | -*/* |
-
Internet Explorer 9 | -application/javascript, */*;q=0.8 |
-
[1] See bug 170789.
-[2] See IE and the Accept Header (IEInternals' MSDN blog).
-When a CSS stylesheet is requested, via the <link rel="stylesheet">
HTML element, most browsers use specific values.
User Agent | -Value | -
---|---|
Firefox 4 [1] | -text/css,*/*;q=0.1 |
-
Internet Explorer 8 or earlier [2] | -*/* |
-
Internet Explorer 9 | -text/css |
-
Safari, Chrome | -text/css,*/*;q=0.1 |
-
Opera 11.10 | -text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 |
-
Konqueror 4.6 | -text/css,*/*;q=0.1 |
-
[1] See bug 170789.
-[2] See IE and the Accept Header (IEInternals' MSDN blog).
diff --git a/files/en-us/web/http/content_negotiation/list_of_default_accept_values/index.md b/files/en-us/web/http/content_negotiation/list_of_default_accept_values/index.md new file mode 100644 index 000000000000000..f627bdd9ab377f2 --- /dev/null +++ b/files/en-us/web/http/content_negotiation/list_of_default_accept_values/index.md @@ -0,0 +1,107 @@ +--- +title: List of default Accept values +slug: Web/HTTP/Content_negotiation/List_of_default_Accept_values +tags: + - Accept + - Content Negotiation + - HTTP + - Reference +--- +{{HTTPSidebar}} + +This article documents the default values for the HTTP [`Accept`](/en-US/docs/Web/HTTP/Headers/Accept) header for specific inputs and browser versions. + +## Default values + +These are the values sent when the context doesn't give better information. Note that all browsers add the `*/*` MIME Type to cover all cases. This is typically used for requests initiated via the address bar of a browser, or via an HTML {{HTMLElement("a")}} element. + +| User Agent | Value | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Firefox 72 and later [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8` | +| Firefox 66 to 71 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` | +| Firefox 65 [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8` | +| Firefox 64 and earlier [1] | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` | +| Safari, Chrome | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8` | +| Safari 5 [2] | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` | +| Internet Explorer 8 [3] | `image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */*` | +| Edge | `text/html, application/xhtml+xml, image/jxr, */*` | +| Opera | `text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1` | + +\[1] This value can be modified using the [`network.http.accept.default`](http://kb.mozillazine.org/Network.http.accept.default) parameter. + +\[2] This is an improvement over earlier `Accept` headers as it no longer ranks `image/png` above `text/html`. + +\[3] See [IE and the Accept Header (IEInternals' MSDN blog)](https://docs.microsoft.com/en-us/archive/blogs/ieinternals/ie-and-the-accept-header). + +## Values for an image + +When requesting an image, like through an HTML {{HTMLElement("img")}} element, user-agent often sets a specific list of media types to be welcomed. + +| User Agent | Value | +| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | +| Firefox 65 and later [1] | `image/webp,*/*` | +| Firefox 47 to 63 [1] | `*/*` | +| Firefox prior to 47 [1] | `image/png,image/*;q=0.8,*/*;q=0.5` | +| Safari (since Mac OS Big Sur) | `image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5` | +| Safari (before Mac OS Big Sur) | `image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5` | +| Chrome | `image/avif,image/webp,image/apng,image/*,*/*;q=0.8` | +| Internet Explorer 9 | `image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5` | +| Internet Explorer 8 or earlier _[source](https://docs.microsoft.com/en-us/archive/blogs/ieinternals/ie-and-the-accept-header)_ | `*/*` | + +\[1] This value can be modified using the `image.http.accept` parameter (_[source](https://searchfox.org/mozilla-central/search?q=image.http.accept)_). + +## Values for a video + +When a video is requested, via the {{HTMLElement("video")}} HTML element, most browsers use specific values. + +| User Agent | Value | +| ------------------------------ | ---------------------------------------------------------------------------------- | +| Firefox 3.6 and later | `video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5` | +| Firefox earlier than 3.6 | _no support for {{HTMLElement("video")}}_ | +| Chrome | `*/*` | +| Internet Explorer 8 or earlier | _no support for {{HTMLElement("video")}}_ | + +## Values for audio resources + +When an audio file is requested, like via the {{HTMLElement("audio")}} HTML element, most browsers use specific values. + +| User Agent | Value | +| ------------------------------ | -------------------------------------------------------------------------------------------- | +| Firefox 3.6 and later [1] | `audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5` | +| Safari, Chrome | `*/*` | +| Internet Explorer 8 or earlier | _no support for {{HTMLElement("audio")}}_ | +| Internet Explorer 9 | ? | + +\[1] See [bug 489071](https://bugzilla.mozilla.org/show_bug.cgi?id=489071). + +## Values for scripts + +When a script is requested, like via the {{HTMLElement("script")}} HTML element, some browsers use specific values. + +| User Agent | Value | +| ---------------------------------- | ----------------------------------- | +| Firefox [1] | `*/*` | +| Safari, Chrome | `*/*` | +| Internet Explorer 8 or earlier [2] | `*/*` | +| Internet Explorer 9 | `application/javascript, */*;q=0.8` | + +\[1] See [bug 170789](https://bugzilla.mozilla.org/show_bug.cgi?id=170789). + +\[2] See [IE and the Accept Header (IEInternals' MSDN blog)](https://docs.microsoft.com/en-us/archive/blogs/ieinternals/ie-and-the-accept-header). + +## Values for a CSS stylesheet + +When a CSS stylesheet is requested, via the `` HTML element, most browsers use specific values. + +| User Agent | Value | +| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| Firefox 4 [1] | `text/css,*/*;q=0.1` | +| Internet Explorer 8 or earlier [2] | `*/*` | +| Internet Explorer 9 | `text/css` | +| Safari, Chrome | `text/css,*/*;q=0.1` | +| Opera 11.10 | `text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1` | +| Konqueror 4.6 | `text/css,*/*;q=0.1` | + +\[1] See [bug 170789](https://bugzilla.mozilla.org/show_bug.cgi?id=170789). + +\[2] See [IE and the Accept Header (IEInternals' MSDN blog)](https://docs.microsoft.com/en-us/archive/blogs/ieinternals/ie-and-the-accept-header). diff --git a/files/en-us/web/http/cookies/index.html b/files/en-us/web/http/cookies/index.html deleted file mode 100644 index 5c3915f2a1a5843..000000000000000 --- a/files/en-us/web/http/cookies/index.html +++ /dev/null @@ -1,252 +0,0 @@ ---- -title: Using HTTP cookies -slug: Web/HTTP/Cookies -tags: - - Advertising - - Browser - - Cookies - - Cookies Article - - Guide - - HTTP - - History - - JavaScript - - Privacy - - Protocols - - Server - - Storage - - Web Development - - data - - request - - tracking ---- -An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to the user's web browser. The browser may store it and send it back with later requests to the same server. - Typically, it is used to tell if two requests came from the same browser — keeping a user logged-in, for example. It remembers stateful information for the stateless HTTP protocol.
- -Cookies are mainly used for three purposes:
- -Cookies were once used for general client-side storage. While this was legitimate when they were the only way to store data on the client, it is now recommended to use modern storage APIs. Cookies are sent with every request, so they can worsen performance (especially for mobile data connections). Modern APIs for client storage are the Web Storage API (localStorage
and sessionStorage
) and IndexedDB.
Note: To see stored cookies (and other storage that a web page can use), you can enable the Storage Inspector in Developer Tools and select Cookies from the storage tree.
-After receiving an HTTP request, a server can send one or more {{HTTPHeader("Set-Cookie")}} headers with the response. The cookie is usually stored by the browser, and then the cookie is sent with requests made to the same server inside a {{HTTPHeader("Cookie")}} HTTP header. An expiration date or duration can be specified, after which the cookie is no longer sent. Additional restrictions to a specific domain and path can be set, limiting where the cookie is sent. For details about the header attributes mentioned below, refer to the {{HTTPHeader("Set-Cookie")}} reference article.
- -Set-Cookie
and Cookie
headersThe {{HTTPHeader("Set-Cookie")}} HTTP response header sends cookies from the server to the user agent. A simple cookie is set like this:
- -Set-Cookie: <cookie-name>=<cookie-value>- -
This shows the server sending headers to tell the client to store a pair of cookies:
- -HTTP/2.0 200 OK -Content-Type: text/html -Set-Cookie: yummy_cookie=choco -Set-Cookie: tasty_cookie=strawberry - -[page content]- -
Then, with every subsequent request to the server, the browser sends back all previously stored cookies to the server using the {{HTTPHeader("Cookie")}} header.
- -GET /sample_page.html HTTP/2.0 -Host: www.example.org -Cookie: yummy_cookie=choco; tasty_cookie=strawberry- -
Note: Here's how to use the Set-Cookie
header in various server-side applications:
The lifetime of a cookie can be defined in two ways:
- -Expires
attribute, or after a period of time specified by the Max-Age
attribute.For example:
- -Set-Cookie: id=a3fWa; Expires=Thu, 31 Oct 2021 07:28:00 GMT;- -
Note: When an Expires
date is set, the time and date set is relative to the client the cookie is being set on, not the server.
If your site authenticates users, it should regenerate and resend session cookies, even ones that already exist, whenever the user authenticates. This technique helps prevent session fixation attacks, where a third party can reuse a user's session.
- -There are a couple of ways to ensure that cookies are sent securely and are not accessed by unintended parties or scripts: the Secure
attribute and the HttpOnly
attribute.
A cookie with the Secure
attribute is sent to the server only with an encrypted request over the HTTPS protocol, never with unsecured HTTP (except on localhost), and therefore can't easily be accessed by a {{Glossary("MitM", "man-in-the-middle")}} attacker. Insecure sites (with http:
in the URL) can't set cookies with the Secure
attribute. However, do not assume that Secure
prevents all access to sensitive information in cookies; for example, it can be read and modified by someone with access to the client's hard disk (or JavaScript if the HttpOnly
attribute is not set).
A cookie with the HttpOnly
attribute is inaccessible to the JavaScript {{domxref("Document.cookie")}} API; it is sent only to the server. For example, cookies that persist server-side sessions don't need to be available to JavaScript, and should have the HttpOnly
attribute. This precaution helps mitigate cross-site scripting (XSS) attacks.
Here is an example:
- -Set-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly- -
The Domain
and Path
attributes define the scope of the cookie: what URLs the cookies should be sent to.
The Domain
attribute specifies which hosts are allowed to receive the cookie. If unspecified, it defaults to the same {{Glossary("host")}} that set the cookie, excluding subdomains. If Domain
is specified, then subdomains are always included. Therefore, specifying Domain
is less restrictive than omitting it. However, it can be helpful when subdomains need to share information about a user.
For example, if Domain=mozilla.org
is set, then cookies are available on subdomains like developer.mozilla.org
.
The Path
attribute indicates a URL path that must exist in the requested URL in order to send the Cookie
header. The %x2F
("/") character is considered a directory separator, and subdirectories match as well.
For example, if Path=/docs
is set, these paths match:
/docs
/docs/Web/
/docs/Web/HTTP
The SameSite
attribute lets servers specify whether/when cookies are sent with cross-site requests (where {{Glossary("Site")}} is defined by the registrable domain), which provides some protection against cross-site request forgery attacks ({{Glossary("CSRF")}}).
It takes three possible values: Strict
, Lax
, and None
. With Strict
, the cookie is sent only to the same site as the one that originated it; Lax
is similar, except that cookies are sent when the user navigates to the cookie's origin site, for example, by following a link from an external site; None
specifies that cookies are sent on both originating and cross-site requests, but only in secure contexts (i.e. if SameSite=None
then the Secure
attribute must also be set). If no SameSite
attribute is set then the cookie is treated as Lax
.
Here is an example:
- -Set-Cookie: mykey=myvalue; SameSite=Strict- -
Note: Standard related to SameSite
recently changed (MDN documents the new behavior above). See the cookies Browser compatibility table for information about how the attribute is handled in specific browser versions:
SameSite=Lax
is the new default if SameSite
is not specified. Previously the default was that cookies were sent for all requests.SameSite=None
must now also specify the Secure
attribute (they require a secure context).The design of the cookie mechanism is such that a server is unable to confirm that a cookie was set on a secure origin or even to tell where a cookie was originally set.
- -A vulnerable application on a sub-domain can set a cookie with the Domain
attribute, which gives access to that cookie on all other subdomains. This mechanism can be abused in a session fixation attack. See session fixation for primary mitigation methods.
As a defense-in-depth measure, however, it is possible to use cookie prefixes to assert specific facts about the cookie. Two prefixes are available:
- -__Host-
Secure
attribute, was sent from a secure origin, does not include a Domain
attribute, and has the Path
attribute set to /
. In this way, these cookies can be seen as "domain-locked".__Secure-
Secure
attribute and was sent from a secure origin. This is weaker than the __Host-
prefix.Cookies with these prefixes that are not compliant with their restrictions are rejected by the browser. Note that this ensures that if a subdomain were to create a cookie with a prefix, it would either be confined to the subdomain or be ignored completely. As the application server checks for a specific cookie name only when determining if the user is authenticated or a CSRF token is correct, this effectively acts as a defense measure against session fixation.
- -Note: On the application server, the web application must check for the full cookie name including the prefix—user agents do not strip the prefix from the cookie before sending it in a request's {{HTTPHeader("Cookie")}} header.
-For more information about cookie prefixes and the current state of browser support, see the Prefixes section of the Set-Cookie reference article.
- -New cookies can be created via JavaScript using the {{domxref("Document.cookie")}} property, and existing cookies can be accessed from JavaScript as well, if the HttpOnly
flag is not set.
document.cookie = "yummy_cookie=choco"; -document.cookie = "tasty_cookie=strawberry"; -console.log(document.cookie); -// logs "yummy_cookie=choco; tasty_cookie=strawberry"- -
Cookies created via JavaScript cannot include the HttpOnly
flag.
Please note the security issues in the Security section below. Cookies available to JavaScript can be stolen through XSS.
- -Note: Information should be stored in cookies with the understanding that all cookie values are visible to, and can be changed by, the end-user. Depending on the application, it may be desirable to use an opaque identifier which is looked-up by the server or to investigate alternative authentication/confidentiality mechanisms such as JSON Web Tokens.
-Ways to mitigate attacks involving cookies:
- -HttpOnly
attribute to prevent access to cookie values via JavaScript.SameSite
attribute set to Strict
or Lax
. (See SameSite cookies, above.) In browsers that support SameSite, this has the effect of ensuring that the authentication cookie is not sent with cross-site requests, so such a request is effectively unauthenticated to the application server.A cookie is associated with a domain. If this domain is the same as the domain of the page you are on, the cookie is called a first-party cookie. If the domain is different, it is a third-party cookie. While the server hosting a web page sets first-party cookies, the page may contain images or other components stored on servers in other domains (for example, ad banners), which may set third-party cookies. These are mainly used for advertising and tracking across the web. See for example the types of cookies used by Google.
- -A third party server can build up a profile of a user's browsing history and habits based on cookies sent to it by the same browser when accessing multiple sites. Firefox, by default, blocks third-party cookies that are known to contain trackers. Third-party cookies (or just tracking cookies) may also be blocked by other browser settings or extensions. Cookie blocking can cause some third-party components (such as social media widgets) to not function as intended.
- -Note: Servers can (and should) set the cookie SameSite attribute to specify whether or not cookies may be sent to third party sites.
-Legislation or regulations that cover the use of cookies include:
- -These regulations have global reach, because they apply to any site on the World Wide Web that is accessed by users from these jurisdictions (the EU and California, with the caveat that California's law applies only to entities with gross revenue over 25 million USD, among other things.)
- -These regulations include requirements such as:
- -There may be other regulations governing the use of cookies in your locality. The burden is on you to know and comply with these regulations. There are companies that offer "cookie banner" code that helps you comply with these regulations.
- -Another approach to storing data in the browser is the Web Storage API. The window.sessionStorage and window.localStorage properties correspond to session and permanent cookies in duration, but have larger storage limits than cookies, and are never sent to a server. More structured and larger amounts of data can be stored using the IndexedDB API, or a library built on it.
- -Other techniques have been created to cause cookies to be recreated after they are deleted, known as "zombie" cookies. These techniques violate the principles of user privacy and user control, may violate data privacy regulations, and could expose a website using them to legal liability.
- -Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz'- -
The origin making the request does not match the origin permitted by the {{HTTPHeader("Access-Control-Allow-Origin")}} header. This error can also occur if the response includes more than one
- Access-Control-Allow-Origin
header.
If the service your code is accessing uses a CORS request under your control, make
- sure it is configured to include your origin in its
- Access-Control-Allow-Origin
header. In addition, confirm that only one such header is
- included in responses, and that it includes only a single origin.
For example, in Apache, add a line such as the following to the server's configuration
- (within the appropriate <Directory>
, <Location>
,
- <Files>
, or <VirtualHost>
section). The
- configuration is typically found in a .conf
file (httpd.conf
- and apache.conf
are common names for these), or in an
- .htaccess
file.
Header set Access-Control-Allow-Origin 'origin'- -
For Nginx, the command to set up this header is:
- -add_header 'Access-Control-Allow-Origin' 'origin'- -
Reason: CORS request did not succeed- -
The {{Glossary("HTTP")}} request which makes use of CORS failed because the HTTP - connection failed at either the network or protocol level. The error is not directly - related to CORS, but is a fundamental network error of some kind.
- -In many cases, it is caused by a browser plugin (e.g. an ad blocker or privacy - protector) blocking the request.
- -Other possible causes include:
- -https
resource that has an invalid certificate will
- cause this error.http
resource from a page with an
- https
origin will also cause this error.https
pages are not permitted to access
- http://localhost
, although this may be changed by Bug 1488740.Reason: CORS disabled- -
A request that needs to use {{Glossary("CORS")}} was attempted, but CORS is disabled in - the user's browser. When this happens, the user needs to turn CORS back on in their - browser.
- -In Firefox, the preference that disables CORS is content.cors.disable
.
- Setting this to true
disables CORS, so whenever that's the case, CORS
- requests will always fail with this error.
Reason: CORS request external redirect not allowed- -
The {{Glossary("CORS")}} request was responded to by the server with an HTTP redirect - to a URL on a different origin than the original request, which is not permitted during - CORS requests.
- -For example, if the page https://service.tld/fetchdata
were requested, and
- the HTTP response is "301 Moved Permanently", "307 Temporary Redirect", or "308
- Permanent Redirect" with a Location
of
- https://anotherservice.net/getdata
, the CORS request will fail in this
- manner.
To fix the problem, update your code to use the new URL as reported by the redirect, - thereby avoiding the redirect.
- -Reason: invalid token ‘xyz’ in CORS header ‘Access-Control-Allow-Headers’- -
The response to the {{Glossary("CORS")}} request that was sent by the server includes - an {{HTTPHeader("Access-Control-Allow-Headers")}} header which includes at least one - invalid header name.
- -The Access-Control-Allow-Headers
header is sent by the server in response
- to a {{Glossary("preflight request")}}; it lets the client know which HTTP headers are permitted in CORS requests.
- If the client {{Glossary("user agent")}} finds among the comma-delineated values
- provided by the header any header name it does not recognize, this error occurs.
This is a problem that most likely can only be fixed on the server side, by modifying
- the server's configuration to no longer send the invalid or unknown header name with the
- Access-Control-Allow-Headers
header. It may also be worth checking to
- ensure that the user agent or HTTP library you're using on the client is up-to-date.
Reason: invalid token ‘xyz’ in CORS header ‘Access-Control-Allow-Methods’- -
The response to the {{Glossary("CORS")}} request that was sent by the server includes - an {{HTTPHeader("Access-Control-Allow-Methods")}} header which includes at least one - invalid method name.
- -The Access-Control-Allow-Methods
header is sent by the server to let the
- client know what HTTP request methods it
- supports for CORS requests. The header's value is a comma-delineated string of HTTP
- method names, such as {{HTTPMethod("GET")}}, {{HTTPMethod("POST")}}, or
- {{HTTPMethod("HEAD")}}. If any of the specified values are not recognized by the client
- {{Glossary("user agent")}}, this error occurs.
This is a problem that most likely can only be fixed on the server side, by modifying
- the server's configuration to no longer send the invalid or unknown method name with the
- Access-Control-Allow-Methods
header. It may also be worth checking to
- ensure that the user agent or HTTP library you're using on the client is up-to-date.
Reason: Did not find method in CORS header ‘Access-Control-Allow-Methods’- -
The HTTP method being used by the {{Glossary("CORS")}} request is not included in the - list of methods specified by the response's - {{HTTPHeader("Access-Control-Allow-Methods")}} header. This header specifies a - comma-delineated list of the HTTP methods which may be used when using CORS to access - the URL specified in the request; if the request is using any other method, this error - occurs.
- -For example, if the response includes:
- -Access-Control-Allow-Methods: GET,HEAD,POST- -
Trying to use a {{HTTPMethod("PUT")}} request will fail with this error.
- -Make sure your code only uses the permitted HTTP methods when accessing the service. -
- -Note: If the server includes any unrecognized or undefined method
- names in its Access-Control-Allow-methods
header, a different error occurs:
- Reason: invalid token ‘xyz' in CORS header ‘Access-Control-Allow-Methods’
.
-
Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’- -
The {{Glossary("CORS")}} request requires that the server permit the use of
- credentials, but the server's {{HTTPHeader("Access-Control-Allow-Credentials")}}
- header's value isn't set to true
to enable their use.
To fix this problem on the client side, revise the code to not request the use of - credentials.
- -true
.false
(it's the
- default value)."omit"
.To eliminate this error by changing the server's configuration, adjust the server's
- configuration to set the Access-Control-Allow-Credentials
header's value to
- true
.
Reason: missing token ‘xyz’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel- -
The Access-Control-Allow-Headers
header is sent by the server to let the client know which headers it supports for {{Glossary("CORS")}} requests. The value of Access-Control-Allow-Headers
should be a comma-delineated list of header names, such as "X-Custom-Information
" or any of the standard but non-basic header names (which are always allowed).
This error occurs when attempting to preflight a header that is not expressly allowed (that is, it's not included in the list specified by the Access-Control-Allow-Headers
header sent by the server). To fix this, the server needs to be updated so that it allows the indicated header, or you need to avoid using that header.
Reason: CORS header 'Access-Control-Allow-Origin' missing- -
The response to the {{Glossary("CORS")}} request is missing the required - {{HTTPHeader("Access-Control-Allow-Origin")}} header, which is used to determine whether - or not the resource can be accessed by content operating within the current origin.
- -If the server is under your control, add the origin of the requesting site to the set
- of domains permitted access by adding it to the Access-Control-Allow-Origin
- header's value.
For example, to allow a site at https://amazing.site to access the resource using CORS, - the header should be:
- -Access-Control-Allow-Origin: https://amazing.site- -
You can also configure a site to allow any site to access it by using the
- *
wildcard. You should only use this for public APIs. Private APIs should
- never use *
, and should instead have a specific domain or domains set. In
- addition, the wildcard only works for requests made with the
- {{htmlattrxref("crossorigin")}} attribute set to anonymous
, and it prevents
- sending credentials like cookies in requests.
Access-Control-Allow-Origin: *- -
Warning: Using the wildcard to allow all sites to access a private - API is a bad idea.
-To allow any site to make CORS requests without using the *
- wildcard (for example, to enable credentials), your server must read the value of the
- request's Origin
header and use that value to set
- Access-Control-Allow-Origin
, and must also set a Vary: Origin
- header to indicate that some headers are being set dynamically depending on the origin.
-
The exact directive for setting headers depends on your web server. In Apache, add a
- line such as the following to the server's configuration (within the appropriate
- <Directory>
, <Location>
,
- <Files>
, or <VirtualHost>
section). The
- configuration is typically found in a .conf
file (httpd.conf
- and apache.conf
are common names for these), or in an
- .htaccess
file.
Header set Access-Control-Allow-Origin 'origin-list'- -
For Nginx, the command to set up this header is:
- -add_header 'Access-Control-Allow-Origin' 'origin-list';- -
Reason: Multiple CORS header ‘Access-Control-Allow-Origin’ not allowed- -
More than one {{HTTPHeader("Access-Control-Allow-Origin")}} header was sent by the - server. This isn't allowed.
- -If you have access to the server you can change your implementation to echo back an
- origin in the Access-Control-Allow-Origin
header. You cannot send back a
- list of origins, because browsers only accept a value that is either a single origin or
- null
Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’- -
The {{Glossary("CORS")}} request was attempted with the credentials flag set, but the server is configured using the wildcard ("*"
) as the value of {{HTTPHeader("Access-Control-Allow-Origin")}}, which doesn't allow the use of credentials.
To correct this problem on the client side, ensure that the credentials flag's value is false
when issuing your CORS request.
true
.false
(it's the default value)."omit"
.If, instead, you need to adjust the server's behavior, you'll need to change the value of Access-Control-Allow-Origin
to grant access to the origin from which the client is loaded.
Reason: CORS header ‘Origin’ cannot be added- -
The {{Glossary("user agent")}} was unable to add the required {{HTTPHeader("Origin")}}
- header to the {{Glossary("HTTP")}} request. All CORS requests must have an
- Origin
header.
This can happen if the JavaScript code is running with enhanced privileges allowing it - access to multiple domains' content, for example.
- -Reason: CORS preflight channel did not succeed- -
The {{Glossary("CORS")}} request requires preflight, preflighting could not be - performed. There are a couple of reasons why preflighting might fail:
- -Reason: CORS request not HTTP- -
{{Glossary("CORS")}} requests may only use the HTTPS URL scheme, but the URL specified
- by the request is of a different type. This often occurs if the URL specifies a local
- file, using a file:///
URL.
To fix this problem, make sure you use HTTPS URLs when issuing requests involving CORS,
- such as {{domxref("XMLHttpRequest")}}, Fetch
- APIs, Web Fonts (@font-face
), and WebGL
- textures, and XSL stylesheets.
When a user opened a page using a file:///
URI in Firefox 67 and earlier,
- the origin of the page was defined as the directory from which the page was opened.
- Resources in the same directory and its subdirectories were treated as having the same
- origin for purposes of the CORS same-origin rule.
In response to CVE-2019-11730,
- Firefox 68 and later define the origin of a page opened using a file:///
- URI as unique. Therefore, other resources in the same directory or its subdirectories no
- longer satisfy the CORS same-origin rule. This new behavior is enabled by default using
- the privacy.file_unique_origin
preference.
Cross-Origin Resource Sharing ({{Glossary("CORS")}}) is a standard that allows a server to relax the same-origin policy. This is used to explicitly allow some cross-origin requests while rejecting others. For example, if a site offers an embeddable service, it may be necessary to relax certain restrictions. Setting up such a CORS configuration isn't necessarily easy and may present some challenges. In these pages, we'll look into some common CORS error messages and how to resolve them.
- -If the CORS configuration isn't setup correctly, the browser console will present an error like "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at $somesite"
indicating that the request was blocked due to violating the CORS security rules. This might not necessarily be a set-up mistake, though. It's possible that the request is in fact intentionally being disallowed by the user's web application and remote external service. However, If the endpoint is meant to be available, some debugging is needed to succeed.
To understand the underlying issue with the CORS configuration, you need to find out which request is at fault and why. These steps may help you do so:
- -The text of the error message will be something similar to the following:
- -Cross-Origin Request Blocked: The Same Origin Policy disallows -reading the remote resource at https://some-url-here. (Reason: -additional information here).- -
Note: For security reasons, specifics about what went wrong with a CORS request are not available to JavaScript code. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser's console for details.
-Firefox's console displays messages in its console when requests fail due to CORS. Part of the error text is a "reason" message that provides added insight into what went wrong. The reason messages are listed below; click the message to open an article explaining the error in more detail and offering possible solutions.
- -Cross-Origin Resource Sharing ({{Glossary("CORS")}}) is an {{Glossary("HTTP")}}-header based mechanism that allows a server to indicate any {{glossary("origin")}}s (domain, scheme, or port) other than its own from which a browser should permit loading of resources. CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.
- -An example of a cross-origin request: the front-end JavaScript code served from https://domain-a.com
uses {{domxref("XMLHttpRequest")}} to make a request for https://domain-b.com/data.json
.
For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest
and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.
The CORS mechanism supports secure cross-origin requests and data transfers between browsers and servers. Modern browsers use CORS in APIs such as XMLHttpRequest
or Fetch to mitigate the risks of cross-origin HTTP requests.
Everyone, really.
- -More specifically, this article is for web administrators, server developers, and front-end developers. Modern browsers handle the client side of cross-origin sharing, including headers and policy enforcement. But the CORS standard means servers have to handle new request and response headers.
- -This cross-origin sharing standard can enable cross-site HTTP requests for:
- -@font-face
within CSS), so that servers can deploy TrueType fonts that can only be cross-site loaded and used by web sites that are permitted to do so.This article is a general discussion of Cross-Origin Resource Sharing and includes a discussion of the necessary HTTP headers.
- -The Cross-Origin Resource Sharing standard works by adding new HTTP headers that let servers describe which origins are permitted to read that information from a web browser. Additionally, for HTTP request methods that can cause side-effects on server data (in particular, HTTP methods other than {{HTTPMethod("GET")}}, or {{HTTPMethod("POST")}} with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with the HTTP {{HTTPMethod("OPTIONS")}} request method, and then, upon "approval" from the server, sending the actual request. Servers can also inform clients whether "credentials" (such as Cookies and HTTP Authentication) should be sent with requests.
- -CORS failures result in errors, but for security reasons, specifics about the error are not available to JavaScript. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser's console for details.
- -Subsequent sections discuss scenarios, as well as provide a breakdown of the HTTP headers used.
- -We present three scenarios that demonstrate how Cross-Origin Resource Sharing works. All these examples use {{domxref("XMLHttpRequest")}}, which can make cross-site requests in any supporting browser.
- -Some requests don't trigger a {{Glossary("Preflight_request","CORS preflight")}}. Those are called simple requests, though the {{SpecName('Fetch')}} spec (which defines CORS) doesn't use that term. A simple request is one that meets all the following conditions:
- -application/x-www-form-urlencoded
multipart/form-data
text/plain
xhr
, no code has called xhr.upload.addEventListener()
to add an event listener to monitor the upload.Note: WebKit Nightly and Safari Technology Preview place additional restrictions on the values allowed in the {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, and {{HTTPHeader("Content-Language")}} headers. If any of those headers have "nonstandard" values, WebKit/Safari does not consider the request to be a "simple request". What values WebKit/Safari consider "nonstandard" is not documented, except in the following WebKit bugs:
-No other browsers implement these extra restrictions, because they're not part of the spec.
-For example, suppose web content at https://foo.example
wishes to invoke content on domain https://bar.other
. Code of this sort might be used in JavaScript deployed on foo.example
:
const xhr = new XMLHttpRequest(); -const url = 'https://bar.other/resources/public-data/'; - -xhr.open('GET', url); -xhr.onreadystatechange = someHandler; -xhr.send(); -- -
This performs a simple exchange between the client and the server, using CORS headers to handle the privileges:
- -Let's look at what the browser will send to the server in this case, and let's see how the server responds:
- -GET /resources/public-data/ HTTP/1.1 -Host: bar.other -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -Accept-Language: en-us,en;q=0.5 -Accept-Encoding: gzip,deflate -Connection: keep-alive -Origin: https://foo.example -- -
The request header of note is {{HTTPHeader("Origin")}}, which shows that the invocation is coming from https://foo.example
.
HTTP/1.1 200 OK -Date: Mon, 01 Dec 2008 00:23:53 GMT -Server: Apache/2 -Access-Control-Allow-Origin: * -Keep-Alive: timeout=2, max=100 -Connection: Keep-Alive -Transfer-Encoding: chunked -Content-Type: application/xml - -[…XML Data…]- -
In response, the server sends back an {{HTTPHeader("Access-Control-Allow-Origin")}} header with Access-Control-Allow-Origin: *
, which means that the resource can be accessed by any origin.
Access-Control-Allow-Origin: *- -
This pattern of the {{HTTPHeader("Origin")}} and {{HTTPHeader("Access-Control-Allow-Origin")}} headers is the simplest use of the access control protocol. If the resource owners at https://bar.other
wished to restrict access to the resource to requests only from https://foo.example
, (i.e no domain other than https://foo.example
can access the resource in a cross-site manner) they would send:
Access-Control-Allow-Origin: https://foo.example
-
-
-Note: When responding to a credentialed requests request, the server must specify an origin in the value of the Access-Control-Allow-Origin
header, instead of specifying the "*
" wildcard.
Unlike simple requests , for "preflighted" requests the browser first sends an HTTP request using the {{HTTPMethod("OPTIONS")}} method to the resource on the other origin, in order to determine if the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data.
- -The following is an example of a request that will be preflighted:
- -const xhr = new XMLHttpRequest(); -xhr.open('POST', 'https://bar.other/resources/post-here/'); -xhr.setRequestHeader('X-PINGOTHER', 'pingpong'); -xhr.setRequestHeader('Content-Type', 'application/xml'); -xhr.onreadystatechange = handler; -xhr.send('<person><name>Arun</name></person>'); -- -
The example above creates an XML body to send with the POST
request. Also, a non-standard HTTP X-PINGOTHER
request header is set. Such headers are not part of HTTP/1.1, but are generally useful to web applications. Since the request uses a Content-Type
of application/xml
, and since a custom header is set, this request is preflighted.
Note: As described below, the actual POST
request does not include the Access-Control-Request-*
headers; they are needed only for the OPTIONS
request.
Let's look at the full exchange between client and server. The first exchange is the preflight request/response:
- -OPTIONS /doc HTTP/1.1 -Host: bar.other -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -Accept-Language: en-us,en;q=0.5 -Accept-Encoding: gzip,deflate -Connection: keep-alive -Origin: https://foo.example -Access-Control-Request-Method: POST -Access-Control-Request-Headers: X-PINGOTHER, Content-Type - -HTTP/1.1 204 No Content -Date: Mon, 01 Dec 2008 01:15:39 GMT -Server: Apache/2 -Access-Control-Allow-Origin: https://foo.example -Access-Control-Allow-Methods: POST, GET, OPTIONS -Access-Control-Allow-Headers: X-PINGOTHER, Content-Type -Access-Control-Max-Age: 86400 -Vary: Accept-Encoding, Origin -Keep-Alive: timeout=2, max=100 -Connection: Keep-Alive -- -
Lines 1 - 10 above represent the preflight request with the {{HTTPMethod("OPTIONS")}} method. The browser determines that it needs to send this based on the request parameters that the JavaScript code snippet above was using, so that the server can respond whether it is acceptable to send the request with the actual request parameters. OPTIONS is an HTTP/1.1 method that is used to determine further information from servers, and is a {{Glossary("Safe/HTTP", "safe")}} method, meaning that it can't be used to change the resource. Note that along with the OPTIONS request, two other request headers are sent (lines 9 and 10 respectively):
- -Access-Control-Request-Method: POST -Access-Control-Request-Headers: X-PINGOTHER, Content-Type -- -
The {{HTTPHeader("Access-Control-Request-Method")}} header notifies the server as part of a preflight request that when the actual request is sent, it will be sent with a POST
request method. The {{HTTPHeader("Access-Control-Request-Headers")}} header notifies the server that when the actual request is sent, it will be sent with a X-PINGOTHER
and Content-Type
custom headers. The server now has an opportunity to determine whether it wishes to accept a request under these circumstances.
Lines 13 - 22 above are the response that the server sends back, which indicate that the request method (POST
) and request headers (X-PINGOTHER
) are acceptable. In particular, let's look at lines 16-19:
Access-Control-Allow-Origin: https://foo.example -Access-Control-Allow-Methods: POST, GET, OPTIONS -Access-Control-Allow-Headers: X-PINGOTHER, Content-Type -Access-Control-Max-Age: 86400- -
The server responds with Access-Control-Allow-Origin: https://foo.example
, restricting access to just the requesting origin domain. It also responds with Access-Control-Allow-Methods
, which says that POST
and GET
are viable methods to query the resource in question (this header is similar to the {{HTTPHeader("Allow")}} response header, but used strictly within the context of access control).
The server also sends Access-Control-Allow-Headers
with a value of "X-PINGOTHER, Content-Type
", confirming that these are permitted headers to be used with the actual request. Like Access-Control-Allow-Methods
, Access-Control-Allow-Headers
is a comma separated list of acceptable headers.
Finally, {{HTTPHeader("Access-Control-Max-Age")}} gives the value in seconds for how long the response to the preflight request can be cached for without sending another preflight request. In this case, 86400 seconds is 24 hours. Note that each browser has a maximum internal value that takes precedence when the Access-Control-Max-Age
is greater.
Once the preflight request is complete, the real request is sent:
- -POST /doc HTTP/1.1 -Host: bar.other -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -Accept-Language: en-us,en;q=0.5 -Accept-Encoding: gzip,deflate -Connection: keep-alive -X-PINGOTHER: pingpong -Content-Type: text/xml; charset=UTF-8 -Referer: https://foo.example/examples/preflightInvocation.html -Content-Length: 55 -Origin: https://foo.example -Pragma: no-cache -Cache-Control: no-cache - -<person><name>Arun</name></person> - -HTTP/1.1 200 OK -Date: Mon, 01 Dec 2008 01:15:40 GMT -Server: Apache/2 -Access-Control-Allow-Origin: https://foo.example -Vary: Accept-Encoding, Origin -Content-Encoding: gzip -Content-Length: 235 -Keep-Alive: timeout=2, max=99 -Connection: Keep-Alive -Content-Type: text/plain - -[Some XML payload] -- -
Not all browsers currently support following redirects after a preflighted request. If a redirect occurs after a preflighted request, some browsers currently will report an error message such as the following.
- --- -The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight
-
-- -Request requires preflight, which is disallowed to follow cross-origin redirect
-
The CORS protocol originally required that behavior but was subsequently changed to no longer require it. However, not all browsers have implemented the change, and so still exhibit the behavior that was originally required.
- -Until browsers catch up with the spec, you may be able to work around this limitation by doing one or both of the following:
- -If that's not possible, then another way is to:
- -Response.url
or XMLHttpRequest.responseURL
in the first step.However, if the request is one that triggers a preflight due to the presence of the Authorization
header in the request, you won't be able to work around the limitation using the steps above. And you won't be able to work around it at all unless you have control over the server the request is being made to.
Note: When making credentialed requests to a different domain, third-party cookie policies will still apply. The policy is always enforced independent of any setup on the server and the client, as described in this chapter.
-The most interesting capability exposed by both {{domxref("XMLHttpRequest")}} or Fetch and CORS is the ability to make "credentialed" requests that are aware of HTTP cookies and HTTP Authentication information. By default, in cross-site XMLHttpRequest
or Fetch invocations, browsers will not send credentials. A specific flag has to be set on the XMLHttpRequest
object or the {{domxref("Request")}} constructor when it is invoked.
In this example, content originally loaded from https://foo.example
makes a simple GET request to a resource on https://bar.other
which sets Cookies. Content on foo.example might contain JavaScript like this:
const invocation = new XMLHttpRequest(); -const url = 'https://bar.other/resources/credentialed-content/'; - -function callOtherDomain() { - if (invocation) { - invocation.open('GET', url, true); - invocation.withCredentials = true; - invocation.onreadystatechange = handler; - invocation.send(); - } -}- -
Line 7 shows the flag on {{domxref("XMLHttpRequest")}} that has to be set in order to make the invocation with Cookies, namely the withCredentials
boolean value. By default, the invocation is made without Cookies. Since this is a simple GET
request, it is not preflighted, but the browser will reject any response that does not have the {{HTTPHeader("Access-Control-Allow-Credentials")}}: true
header, and not make the response available to the invoking web content.
Here is a sample exchange between client and server:
- -GET /resources/credentialed-content/ HTTP/1.1 -Host: bar.other -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0 -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -Accept-Language: en-us,en;q=0.5 -Accept-Encoding: gzip,deflate -Connection: keep-alive -Referer: https://foo.example/examples/credential.html -Origin: https://foo.example -Cookie: pageAccess=2 - -HTTP/1.1 200 OK -Date: Mon, 01 Dec 2008 01:34:52 GMT -Server: Apache/2 -Access-Control-Allow-Origin: https://foo.example -Access-Control-Allow-Credentials: true -Cache-Control: no-cache -Pragma: no-cache -Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT -Vary: Accept-Encoding, Origin -Content-Encoding: gzip -Content-Length: 106 -Keep-Alive: timeout=2, max=100 -Connection: Keep-Alive -Content-Type: text/plain - -[text/plain payload] -- -
Although line 10 contains the Cookie destined for the content on https://bar.other
, if bar.other did not respond with an {{HTTPHeader("Access-Control-Allow-Credentials")}}: true
(line 17) the response would be ignored and not made available to web content.
CORS-preflight requests must never include credentials. The response to a preflight request must specify Access-Control-Allow-Credentials: true
to indicate that the actual request can be made with credentials.
Note: Some enterprise authentication services require TLS client certificates be sent in preflight requests, in contravention of the {{SpecName("Fetch","#cors-protocol-and-credentials")}} specification.
-Firefox 87 allows this non-compliant behavior to be enabled by setting the preference: network.cors_preflight.allow_client_cert
to true
({{bug(1511151)}}). Chromium-based browsers currently always send TLS client certificates in CORS preflight requests (Chrome bug 775438).
When responding to a credentialed request, the server must specify an origin in the value of the Access-Control-Allow-Origin
header, instead of specifying the "*
" wildcard.
Because the request headers in the above example include a Cookie
header, the request would fail if the value of the Access-Control-Allow-Origin
header was "*". But it does not fail: Because the value of the Access-Control-Allow-Origin
header is "https://foo.example
" (an actual origin) rather than the "*
" wildcard, the credential-cognizant content is returned to the invoking web content.
Note that the Set-Cookie
response header in the example above also sets a further cookie. In case of failure, an exception—depending on the API used—is raised.
Note that cookies set in CORS responses are subject to normal third-party cookie policies. In the example above, the page is loaded from foo.example
, but the cookie on line 20 is sent by bar.other
, and would thus not be saved if the user has configured their browser to reject all third-party cookies.
Cookie in the request (line 10) may also be suppressed in normal third-party cookie policies. The enforced cookie policy may therefore nullify the capability described in this chapter, effectively prevents you from making credentialed requests whatsoever.
- -Cookie policy around the SameSite attribute would apply.
- -This section lists the HTTP response headers that servers send back for access control requests as defined by the Cross-Origin Resource Sharing specification. The previous section gives an overview of these in action.
- -A returned resource may have one {{HTTPHeader("Access-Control-Allow-Origin")}} header, with the following syntax:
- -Access-Control-Allow-Origin: <origin> | * -- -
Access-Control-Allow-Origin
specifies either a single origin, which tells browsers to allow that origin to access the resource; or else — for requests without credentials — the "*
" wildcard, to tell browsers to allow any origin to access the resource.
For example, to allow code from the origin https://mozilla.org
to access the resource, you can specify:
Access-Control-Allow-Origin: https://mozilla.org -Vary: Origin- -
If the server specifies a single origin (that may dynamically change based on the requesting origin as part of a allowlist) rather than the "*
" wildcard, then the server should also include Origin
in the {{HTTPHeader("Vary")}} response header — to indicate to clients that server responses will differ based on the value of the {{HTTPHeader("Origin")}} request header.
The {{HTTPHeader("Access-Control-Expose-Headers")}} header adds the specified headers to the allowlist that JavaScript (such as {{domxref("XMLHttpRequest.getResponseHeader()","getResponseHeader()")}}) in browsers is allowed to access.
- -Access-Control-Expose-Headers: <header-name>[, <header-name>]* -- -
For example, the following:
- -Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header -- -
…would allow the X-My-Custom-Header
and X-Another-Custom-Header
headers to be exposed to the browser.
The {{HTTPHeader("Access-Control-Max-Age")}} header indicates how long the results of a preflight request can be cached. For an example of a preflight request, see the above examples.
- -Access-Control-Max-Age: <delta-seconds> -- -
The delta-seconds
parameter indicates the number of seconds the results can be cached.
The {{HTTPHeader("Access-Control-Allow-Credentials")}} header indicates whether or not the response to the request can be exposed when the credentials
flag is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. Note that simple GET
requests are not preflighted, and so if a request is made for a resource with credentials, if this header is not returned with the resource, the response is ignored by the browser and not returned to web content.
Access-Control-Allow-Credentials: true -- -
Credentialed requests are discussed above.
- -The {{HTTPHeader("Access-Control-Allow-Methods")}} header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.
- -Access-Control-Allow-Methods: <method>[, <method>]* -- -
An example of a {{Glossary("preflight request")}} is given above, including an example which sends this header to the browser.
- -The {{HTTPHeader("Access-Control-Allow-Headers")}} header is used in response to a {{Glossary("preflight request")}} to indicate which HTTP headers can be used when making the actual request. This header is the server side response to the browser's {{HTTPHeader("Access-Control-Request-Headers")}} header.
- -Access-Control-Allow-Headers: <header-name>[, <header-name>]* -- -
This section lists headers that clients may use when issuing HTTP requests in order to make use of the cross-origin sharing feature. Note that these headers are set for you when making invocations to servers. Developers using cross-site {{domxref("XMLHttpRequest")}} capability do not have to set any cross-origin sharing request headers programmatically.
- -The {{HTTPHeader("Origin")}} header indicates the origin of the cross-site access request or preflight request.
- -Origin: <origin> -- -
The origin is a URL indicating the server from which the request initiated. It does not include any path information, but only the server name.
- -Note: The origin
value can be null
.
Note that in any access control request, the {{HTTPHeader("Origin")}} header is always sent.
- -The {{HTTPHeader("Access-Control-Request-Method")}} is used when issuing a preflight request to let the server know what HTTP method will be used when the actual request is made.
- -Access-Control-Request-Method: <method> -- -
Examples of this usage can be found above.
- -The {{HTTPHeader("Access-Control-Request-Headers")}} header is used when issuing a preflight request to let the server know what HTTP headers will be used when the actual request is made (such as with {{domxref("XMLHttpRequest.setRequestHeader()","setRequestHeader()")}}). This browser side header will be answered by the complementary server side header of {{HTTPHeader("Access-Control-Allow-Headers")}}.
- -Access-Control-Request-Headers: <field-name>[, <field-name>]* -- -
Examples of this usage can be found above.
- -Specification | -Status | -Comment | -
---|---|---|
{{SpecName('Fetch', '#cors-protocol', 'CORS')}} | -{{Spec2('Fetch')}} | -New definition; supplants W3C CORS specification. | -
{{Compat("http.headers.Access-Control-Allow-Origin")}}
- -Cross-Origin Resource Policy is a policy set by the Cross-Origin-Resource-Policy
HTTP header that lets web sites and applications opt in to protection against certain requests from other origins (such as those issued with elements like <script>
and <img>
), to mitigate speculative side-channel attacks, like Spectre, as well as Cross-Site Script Inclusion attacks.
CORP is an additional layer of protection beyond the default {{Glossary("same-origin policy")}}. Cross-Origin Resource Policy complements Cross-Origin Read Blocking (CORB), which is a mechanism to prevent some cross-origin reads by default.
- -Note: The policy is only effective for no-cors
requests, which are issued by default for CORS-safelisted methods/headers.
As this policy is expressed via a response header, the actual request is not prevented—rather, the browser prevents the result from being leaked by stripping the response body.
- -The concept was originally proposed in 2012 (as From-Origin
), but resurrected in Q2 of 2018 and implemented in Safari and Chromium.
In early 2018, two side-channel hardware vulnerabilities known as Meltdown and Spectre were disclosed. These vulnerabilities allowed sensitive data disclosure due to a race condition which arose as part of speculative execution functionality, designed to improve performance.
- -In response, Chromium shipped Cross-Origin Read Blocking, which automatically protects certain resources (of Content-Type
HTML, JSON and XML) against cross-origin reads. If the application does not serve a no-sniff
directive, Chromium will attempt to guess the Content-Type
and apply the protection anyway.
Cross-Origin Resource Policy is an opt-in response header which can protect any resource; there is no need for browsers to sniff MIME types.
- -Note: Due to a bug in Chrome, setting Cross-Origin-Resource-Policy can break PDF rendering, preventing visitors from being able to read past the first page of some PDFs. Exercise caution using this header in a production environment.
-Web applications set a Cross-Origin Resource Policy via the {{HTTPHeader("Cross-Origin-Resource-Policy")}} HTTP response header, which accepts one of three values:
- -same-site
Only requests from the same {{Glossary("Site")}} can read the resource.
- -Warning: This is less secure than an {{Glossary("origin")}}. The algorithm for checking if two origins are same site is defined in the HTML standard and involves checking the registrable domain.
-same-origin
cross-origin
Cross-Origin-Resource-Policy: same-site | same-origin | cross-origin- -
During a cross-origin resource policy check, if the header is set, the browser will deny no-cors
requests issued from a different origin/site.
{{Compat("http.headers.Cross-Origin-Resource-Policy")}}
- -Specification | -Status | -Comment | -
---|---|---|
{{SpecName("Fetch", '#cross-origin-resource-policy-header')}} | -{{Spec2("Fetch", '#cross-origin-resource-policy-header')}} | -Initial definition | -
The HTTP {{HTTPHeader("Content-Security-Policy")}} (CSP)
- connect-src
directive restricts the URLs which can be
- loaded using script interfaces. The APIs that are restricted are:
Note: connect-src 'self'
does not resolve to websocket
- schemas in all browsers, more info in this issue.
CSP version | -1 | -
---|---|
Directive type | -{{Glossary("Fetch directive")}} | -
{{CSP("default-src")}} fallback | -Yes. If this directive is absent, the user agent will look for the
- default-src directive. |
-
One or more sources can be allowed for the connect-src policy:
- -Content-Security-Policy: connect-src <source>; -Content-Security-Policy: connect-src <source> <source>; -- -
{{page("/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src", - "common_sources")}}
- -Given this CSP header:
- -Content-Security-Policy: connect-src https://example.com/- -
The following connections are blocked and won't load:
- -<a ping="https://not-example.com"> - -<script> - var xhr = new XMLHttpRequest(); - xhr.open('GET', 'https://not-example.com/'); - xhr.send(); - - var ws = new WebSocket("https://not-example.com/"); - - var es = new EventSource("https://not-example.com/"); - - navigator.sendBeacon("https://not-example.com/", { ... }); -</script>- -
{{Compat}}
- -xhr-src
was used in place of the
- connect-src
directive and only restricted the use of
- {{domxref("XMLHttpRequest")}}.CSP version | +1 | +
---|---|
Directive type | +{{Glossary("Fetch directive")}} | +
{{CSP("default-src")}} fallback | +
+ Yes. If this directive is absent, the user agent will look for the
+ default-src directive.
+ |
+
The HTTP {{HTTPHeader("Content-Security-Policy")}} (CSP) default-src
directive serves as a fallback for the other CSP {{Glossary("fetch directive", "fetch directives")}}. For each of the following directives that are absent, the user agent looks for the default-src
directive and uses this value for it:
CSP version | -1 | -
---|---|
Directive type | -{{Glossary("Fetch directive")}} | -
One or more sources can be allowed for the default-src
policy:
Content-Security-Policy: default-src <source>; -Content-Security-Policy: default-src <source> <source>; -- -
<source> can be one of the following:
- -<host-source>
'*'
), and you may use a wildcard (again, '*'
) as the port number, indicating that all legal ports are valid for the source.http://*.example.com
: Matches all attempts to load from any subdomain of example.com using the http:
URL scheme.mail.example.com:443
: Matches all attempts to access port 443 on mail.example.com.https://store.example.com
: Matches all attempts to access store.example.com using https:
.*.example.com
: Matches all attempts to load from any subdomain of example.com using the current protocol.<scheme-source>
http:
or https:
. The colon is required. Unlike other values below, single quotes shouldn't be used. You can also specify data schemes (not recommended).
- data:
Allows data:
URIs to be used as a content source. This is insecure; an attacker can also inject arbitrary data: URIs. Use this sparingly and definitely not for scripts.mediastream:
Allows mediastream:
URIs to be used as a content source.blob:
Allows blob:
URIs to be used as a content source.filesystem:
Allows filesystem:
URIs to be used as a content source.'self'
blob
and filesystem
from source directives. Sites needing to allow these content types can specify them using the Data attribute.'unsafe-eval'
eval()
and similar methods for creating code from strings. You must include the single quotes.'unsafe-hashes'
javascript:
URLs, this is a safer method than using the unsafe-inline
expression.'unsafe-inline'
javascript:
URLs, inline event handlers, and inline {{HTMLElement("style")}} elements. The single quotes are required.'none'
'nonce-<base64-value>'
'unsafe-inline'
which could still be set for older browsers without nonce support.
- Note: The CSP nonce
source can only be applied to nonceable elements (e.g., as the {{HTMLElement("img")}} element has no nonce
attribute, there is no way to associate it with this CSP source).
'<hash-algorithm>-<base64-value>'
script-src
for external scripts.'strict-dynamic'
strict-dynamic
source expression specifies that the trust explicitly given to a script present in the markup, by accompanying it with a nonce or a hash, shall be propagated to all the scripts loaded by that root script. At the same time, any allow-list or source expressions such as 'self'
or 'unsafe-inline'
are ignored. See script-src for an example.'report-sample'
If there are other directives specified, default-src
does not influence them. The following header:
Content-Security-Policy: default-src 'self'; script-src https://example.com- -
is the same as:
- -Content-Security-Policy: connect-src 'self'; - font-src 'self'; - frame-src 'self'; - img-src 'self'; - manifest-src 'self'; - media-src 'self'; - object-src 'self'; - script-src https://example.com; - style-src 'self'; - worker-src 'self'- -
{{Compat}}
- -upgrade-insecure-requests
block-all-mixed-content
require-sri-for
{{experimental_inline}}CSP version | +1 | +
---|---|
Directive type | +{{Glossary("Fetch directive")}} | +
The HTTP {{HTTPHeader("Content-Security-Policy")}} (CSP) require-trusted-types-for
{{experimental_inline}} directive instructs user agents to control the data passed to DOM XSS sink functions, like {{DOMxRef("Element.innerHTML")}} setter.
When used, those functions only accept non-spoofable, typed values created by Trusted Type policies, and reject strings. Together with trusted-types
directive, which guards creation of Trusted Type policies, this allows authors to define rules guarding writing values to the DOM and thus reducing the DOM XSS attack surface to small, isolated parts of the web application codebase, facilitating their monitoring and code review.
Content-Security-Policy: require-trusted-types-for 'script'; -- -
'script'
// Content-Security-Policy: require-trusted-types-for 'script'; trusted-types foo; - -const attackerInput = '<svg onload="alert(/cross-site-scripting/)" />'; -const el = document.createElement('div'); - -if (typeof trustedTypes !== 'undefined') { - // Create a policy that can create TrustedHTML values - // after sanitizing the input strings with DOMPurify library. - const sanitizer = trustedTypes.createPolicy('foo', { - createHTML: (input) => DOMPurify.sanitize(input) - }); - - el.innerHTML = sanitizer.createHTML(attackerInput); // Puts the sanitized value into the DOM. - el.innerHTML = attackerInput; // Rejects a string value; throws a TypeError. -} -- -
A polyfill for Trusted Types is available on Github.
- -{{Compat}}
- -The HTTP {{HTTPHeader("Content-Security-Policy")}} (CSP)
- sandbox
directive enables a sandbox for the requested
- resource similar to the {{HTMLElement("iframe")}} {{htmlattrxref("sandbox", "iframe")}}
- attribute. It applies restrictions to a page's actions including preventing popups,
- preventing the execution of plugins and scripts, and enforcing a same-origin policy.
CSP version | -1.1 / 2 | -
---|---|
Directive type | -{{Glossary("Document directive")}} | -
This directive is not supported in the - {{HTMLElement("meta")}} element or by the - {{HTTPHeader("Content-Security-policy-Report-Only")}} header field. | -
Content-Security-Policy: sandbox; -Content-Security-Policy: sandbox <value>; -- -
where <value>
can optionally be one of the following values:
allow-downloads
allow-downloads-without-user-activation
{{experimental_inline}}allow-forms
allow-modals
allow-orientation-lock
allow-pointer-lock
allow-popups
window.open
, target="_blank"
,
- showModalDialog
). If this keyword is not used, that functionality will
- silently fail.allow-popups-to-escape-sandbox
allow-presentation
allow-same-origin
allow-scripts
allow-storage-access-by-user-activation
{{experimental_inline}}allow-top-navigation
allow-top-navigation-by-user-activation
Content-Security-Policy: sandbox allow-scripts;- -
{{Compat}}
- -CSP version | +1.1 / 2 | +
---|---|
Directive type | +{{Glossary("Document directive")}} | +
+ This directive is not supported in the {{HTMLElement("meta")}} + element or by the + {{HTTPHeader("Content-Security-policy-Report-Only")}} + header field. + | +
The HTTP {{HTTPHeader("Content-Security-Policy")}} (CSP)
- script-src-attr
directive specifies valid sources for
- JavaScript inline event handlers. This includes only inline script event handlers like
- onclick
, but not URLs loaded directly into {{HTMLElement("script")}}
- elements.
CSP version | -3 | -
---|---|
Directive type | -{{Glossary("Fetch directive")}} | -
{{CSP("default-src")}} fallback | -Yes. If this directive is absent, the user agent will look for
- the {{CSP("script-src")}} directive, and if both of them are absent, fallback
- to default-src directive. |
-
One or more sources can be allowed for the script-src-attr
policy:
Content-Security-Policy: script-src-attr <source>; -Content-Security-Policy: script-src-attr <source> <source>; -- -
script-src-attr
can be used in conjunction with {{CSP("script-src")}}:
Content-Security-Policy: script-src <source>; -Content-Security-Policy: script-src-attr <source>; -- -
<host-source>
'*'
), and you may use a wildcard (again, '*'
) as the port number, indicating that all legal ports are valid for the source.http://*.example.com
: Matches all attempts to load from any subdomain of example.com using the http:
URL scheme.mail.example.com:443
: Matches all attempts to access port 443 on mail.example.com.https://store.example.com
: Matches all attempts to access store.example.com using https:
.*.example.com
: Matches all attempts to load from any subdomain of example.com using the current protocol.<scheme-source>
http:
or https:
. The colon is required. Unlike other values below, single quotes shouldn't be used. You can also specify data schemes (not recommended).
- data:
Allows data:
URIs to be used as a content source. This is insecure; an attacker can also inject arbitrary data: URIs. Use this sparingly and definitely not for scripts.mediastream:
Allows mediastream:
URIs to be used as a content source.blob:
Allows blob:
URIs to be used as a content source.filesystem:
Allows filesystem:
URIs to be used as a content source.'self'
blob
and filesystem
from source directives. Sites needing to allow these content types can specify them using the Data attribute.'unsafe-eval'
eval()
and similar methods for creating code from strings. You must include the single quotes.'unsafe-hashes'
javascript:
URLs, this is a safer method than using the unsafe-inline
expression.'unsafe-inline'
javascript:
URLs, and inline event handlers. The single quotes are required.'none'
'nonce-<base64-value>'
'unsafe-inline'
which could still be set for older browsers without nonce support.
- Note: The CSP nonce
source can only be applied to nonceable elements (e.g., as the {{HTMLElement("img")}} element has no nonce
attribute, there is no way to associate it with this CSP source).
'<hash-algorithm>-<base64-value>'
script-src
for external scripts.'strict-dynamic'
strict-dynamic
source expression specifies that the trust explicitly given to a script present in the markup, by accompanying it with a nonce or a hash, shall be propagated to all the scripts loaded by that root script. At the same time, any allow-list or source expressions such as 'self'
or 'unsafe-inline'
are ignored. See script-src for an example.'report-sample'
If script-src-attr
is absent, User Agent falls back to
- the {{CSP("script-src")}} directive, and if that is absent as well, to
- {{CSP("default-src")}}.
{{Compat}}
- -CSP version | +3 | +
---|---|
Directive type | +{{Glossary("Fetch directive")}} | +
{{CSP("default-src")}} fallback | +
+ Yes. If this directive is absent, the user agent will look for
+ the {{CSP("script-src")}} directive, and if both of them are
+ absent, fallback to default-src directive.
+ |
+