autocomplete: fix cache issue related to content negotiation.
This is the scenario: * You type something in autocomplete, let's say 'touhou'. * Autocomplete calls /autocomplete?search[query]=touhou&search[type]=tag_query * The endpoint returns JSON, because the autocomplete call sets an `Accept: application/json` header requesting JSON. * Visit /autocomplete?search[query]=touhou&search[type]=tag_query in your browser. * Notice that the cached JSON response is incorrectly returned, not an HTML response like the browser requested. The problem is that the response type is chosen based on the Accept header, but the response didn't set the `Vary: Accept` header, so the browser doesn't know the response type can vary and so it incorrectly returns the cached response. This issue is partially fixed by Rails 6.1 ([1]), which properly sets the `Vary: Accept` header when the response depends on the Accept header. However, the next issue is that Cloudflare doesn't respect the Vary header at all ([2], [3]). Therefore we can't use the Accept header to pick the format, instead we have explicitly specify the format with /autocomplete.json. This is clearer and better for caching anyway. Using the `Vary: Accept` header reduces the cache hit rate, because the exact format of the Accept header varies across browsers, which fragments the cache. Whew. [1] https://github.com/rails/rails/pull.36213 [2] https://community.cloudflare.com/t/cloudflare-cdn-cache-to-support-http-vary-header/160802 [3] https://support.cloudflare.com/hc/en-us/articles/115003206852 [4] https://www.smashingmagazine.com/2017/11/understanding-vary-header/
This commit is contained in:
@@ -201,7 +201,7 @@ Autocomplete.render_item = function(list, item) {
|
||||
};
|
||||
|
||||
Autocomplete.autocomplete_source = function(query, type) {
|
||||
return $.getJSON("/autocomplete", {
|
||||
return $.getJSON("/autocomplete.json", {
|
||||
"search[query]": query,
|
||||
"search[type]": type,
|
||||
"limit": Autocomplete.MAX_RESULTS
|
||||
|
||||
Reference in New Issue
Block a user