3

I am building a frontend and backend application. Using If none match header in the request, my server is returning 304 status but chrome always shows 200 status. Same implementation works well with Firefox and IE. All the headers are placed properly I have added cache-control to max-age 0 and always revalidate. However chrome is successfully showing the cached data but why I don't see 304 status in the network Below are the images from chrome and Firefox network panel

Image from chrome Image from Firefox

My backend is built in .net core and I have used action filter attribute to return ETag and 304 status, below is the code

public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){ var isRequestMethodGet = context.HttpContext.Request.Method == "GET";
    bool isModified = false;
    string authToken = "";
        var path = context.HttpContext.Request.Path.ToString() + context.HttpContext.Request.QueryString.ToString();
        if (context.HttpContext.Request.Headers.ContainsKey("Authorization"))
        {
            authToken = context.HttpContext.Request.Headers["Authorization"];
        }

        var etag = GetETag(path, authToken);
        if (isRequestMethodGet)
        {
            var myId = context.HttpContext.Request.Headers["myId"].ToString();
            var value = await distributedCacheRepository.GetCachedItem($"{redisPrefix}-{myId}");
            if (value != null)
            {
                if (context.HttpContext.Request.Headers.Keys.Contains("If-None-Match") && context.HttpContext.Request.Headers["If-None-Match"].ToString() == etag)
                {
                    isModified = true;
                    context.HttpContext.Response.StatusCode = 304;
                    context.Result = new StatusCodeResult((int)HttpStatusCode.NotModified);
                }
            }
            else
            {
                await distributedCacheRepository.InsertKeyValueAsync($"{redisPrefix}-{myId}", myId);
            }
        }

        if(!isRequestMethodGet || !isModified)
        {
            await next();
        }

       context.HttpContext.Response.Headers.Add("cache-control", new[] { "no-transform", "must-revalidate", "max-age=0" });
       context.HttpContext.Response.Headers.Add("vary", new[] { "Accept", "Accept-Encoding", "Authorization", "Cookie" });           
       context.HttpContext.Response.Headers.Add("ETag", new[] { etag }); }
amit kumar
  • 29
  • 5
  • @PavelAnikhouski Thanks for you reply, I have added the code from .net core which returns 304 status based on Etag – amit kumar May 05 '20 at 09:23
  • If, like me, you think it's a chrome bug, you can have a look at https://bugs.chromium.org/p/chromium/issues/detail?id=1269602 – cube45 Nov 15 '21 at 14:26

1 Answers1

1

Are you sending request to a different port/domain ? I had same issue as you did, server returns 304 (checked via postman) but chrome shows as 200.
Here's how I found out why:

  1. In my swagger doc, 304 is returned (request sent from localhost:8083 to localhost:8083)
  2. In my application, same request but 200 is returned (request sent from localhost:4300 to localhost:8083)
  3. So I proxy my application request to same domain (request sent from localhost:4300 to localhost:4300 then proxy to localhost:8083)
  4. I get 304 as expected
Dharman
  • 30,962
  • 25
  • 85
  • 135
ExploreEv
  • 725
  • 8
  • 8