Etag (Entity Tag) is an HTTP response header used as an identifier to determine the version of a resource transmitted after an HTTP request sent to the server. With the use of HTTP Etag, the caching system used in client - server communication is used much more efficiently. With the etag header used after a request sent to the web server, it can be determined that the requested resource is the same as the resource in the cache, preventing the server from repeatedly processing for unchanged resources and returning a full response containing the same resources.
The etag, which is used as a validator to compare the differences between the version in the cache and the current version hosted on the server of a locally cached document downloaded by sending a request by the client, aims to ensure efficient operation of the caching system.
A new etag (entity tag) is created by the server when a document that was previously cached by sending a request by the client is modified by the server. In the request sent by the client again, the differences between the cached document and the updated document are checked using the etag value and the web server is expected to send a full HTTP response according to the novelty.
In summary, Etag is a web-side fingerprint for efficient caching of resources in client server communication and efficient use of server bandwith limits.
ETag Syntax
HTTP Etag header is created by typing ASCII characters in double quotes (string).
Below you can view the syntax structures for 2 different validator types, weak and strong;
ETag: W/"<etag_value>"
ETag: "<etag_value>"
Etag: W/"12345681231-36b" (Weak validator)
Etag: "12345681231-tr34" (Strong Validator)
ETag Directives
E-tag directives can be analyzed in 2 different structures: Weak validator and Etag string (Strong Validator without w/).
Weak Validator (w/)
In the examples above, the E-Tag structure starting with W/ is called a weak validator. Weak validators are much easier to create on the server side compared to strong validators, but they are weak compared to the strong E-Tag structure in terms of source version comparison. This is because when a weak validator evaluates between 2 different versions of a resource, it checks whether the resources are identical in terms of content, but this check is not byte-to-byte, but semantic (semantic) compatibility of the content. For this reason, weak etag validators prevent caching in byte range requests.
For example: In a scenario where the content is exactly the same on a page cached using a weak validator, elements that are not related in terms of content but structurally changed on the page, such as a change in the date, a change in the number of likes, etc., are not taken into account in the old and new comparison when using a weak validator. In other words, when using the weak validator, as long as there is no contextual change on the page, small metric differences such as a change in the date, a change in the number of likes, etc. are not considered as changes and the resources are considered identical.
Etag Value (Strong Validator)
The Entity Tag (Etag) value represents the requested resource with a unique string value. The etag value, which represents the cached and requested resource with a unique string value, is updated according to the new resource sent when the resource changes and the new resource is sent in response. The classic etag value, called strong validator, consists of ASCII characters written as a string in double quotes as mentioned above. When there is no W/ markup in the HTTP Etag header, the etag is treated directly as a strong validator. Typically, the ETag value is a hashed summary of the content, the last modification timestamp, or just a revision number.
How Does ETag Work?
In typical usage, when a request is sent for a URL, the web server returns the current state of the resource with the corresponding ETag value placed in the "ETag" field in an HTTP response header.
For example:
Default HTTP Headers (Cache control / expire header)
ETag: "246231231123123be"
The resource sent with the HTTP response header can be cached on the client side along with the Etag value and other HTTP headers sent from the server. After the caching is done, when another request is sent by the client to the same resource, the headers such as cache control or expires header used during the first caching are checked to see if the cache status of the resource is up to date. If the cached file is up to date according to the cache header used, the resource is loaded directly from the local cache. On the contrary, if the cache control or expires header of the cached file is outdated, the etag value along with the if-none-match header from the client is returned to the server as a response and a new request is sent.
If-None-Match: "246231231123be"
In this subsequent request, the server can now compare the client's cached ETag with the current ETag for the current version of the resource. If the ETag values match, i.e. the resource has not changed, the server can return a very short response with HTTP 304 "Not Modified" response code indicating that the resource has not changed.
However, if the ETags do not match, this means that the resource has most likely been changed on the server side and a full response containing the contents of the resource along with an HTTP 200 status code and a new etag will be returned in response, as if the ETags were not used. In this case, the client may decide to replace the previously cached version with the newly returned representation of the resource and the new ETag.
The if-modified-since http header can also be used as a case-dependent validator in the second request sent after the file cached with the HTTP cache-control header or expire-headers has become outdated. Similar to the etag value, using the if-modified-since: header instead of if-none-match, the last-modified value specified at the time of caching can be used as a validator value to check the cache's timeliness and the date the file changed.
Example:
HTTP request default headers +
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
In the second request sent after the cache is outdated, a request like the one above is sent from the client to the web server. In this request, unlike in the etag example above, the time when the last-modified header was first cached is sent with the if-modified-since header and the server is asked whether the cached file has been updated since then.
In response to the request, the server sends the new update date with http 200 and the last-modified: response header if the resource has been updated. If the resource has not changed since the caching date, the HTTP 304 response code is returned as in the Etag check and caching continues on the same resource version.
Using etag and last-modified-date together (they can be used separately). When the cached resource changes, a process like the one in the above image example takes place. Image-Source: https://developer.mozilla.org/
How to Check Etags with a Browser?
From any of today's modern web browsers, a user can check the ETags for each web page resource individually.
Below you can see how to check the ETag value of the resources of a web page via Google Chrome. The process and check output is similar for all modern web browsers.
Checking the ETag Value with Chrome
You can follow the steps below to check the etag value via Chrome.
- After logging in to the web page you want to check the etag values, press f12 on Chrome. (You can reach the same screen by right-clicking and then examining instead of F12).
- Log in to the network panel on the Chrome DevTools screen.
- Click on any of the web page sources specified on the Network screen.
- On the screen that opens, in the Headers section, you can view the request headers that you send to the server from your browser and the responses that the server returns to you as a response.
- In the Response section, you can view the Etag (if used) header transmitted by the web server and the generated ETag value. If Etag is not used, you can display the last-modified header instead (if used).
Sample HTTP (weak) etag and last-modified header via Chrome Devtools