Make WordPress Core

Opened 3 years ago

Closed 3 years ago

#57938 closed defect (bug) (duplicate)

wp_get_nocache_headers should contain no-store by default

Reported by: dekadinious's profile Dekadinious Owned by:
Milestone: Priority: normal
Severity: normal Version: 6.1.1
Component: Cache API Keywords:
Focuses: Cc:

Description

I have tried to figure out a bizarre edge-case problem for the last three months. We run a huge WooCommerce store. I could reproduce this locally on a completely clean install with only WooCommerce, Storefront, and Klarna Checkout for WooCommerce.

  1. User adds a product to the cart
  2. User goes to the checkout
  3. User fills in the Klarna Checkout iFrame
  4. User clicks the back button to check something in the cart (or goes to another page)
  5. User clicks the forward button or goes back to the checkout

In step 4 the customer object in WooCommerce has the users shipping postcode. At step 5, it was gone. This meant that at step 3 the user was presented with shipping options, but at step 5 they were mysteriously gone.

I have been down the largest rabbit hole of my life on this one, and here is what I found. This problem was not consistently reproducible, so I needed to find out what the difference was between a scenario where it would appear and a scenario where it would not. I will spare you the details of how I found it, but here is the deal:

WooCommerce has a hidden input field for "shipping_postcode". The first time a new user hits the checkout page, this input field has no value. When the user fills in the Klarna Checkout iFrame, the user's session and customer object is updated with the postcode.

The expected result of navigating away from the checkout and back again is that the page renders fresh from the server. This will mean that the input field will have the value of the customer's postcode.

This is important because right after the page loads WooCommerce will fire an AJAX call that takes this value and updates the customer object.

What happened in my testing was that since wp_get_nocache_headers doesn't include no-store, the checkout page was actually loaded from the browser cache. This meant that the postcode was not set in the input field, because the page was not rendered from the server where the postcode is available in the customer object. So the AJAX call updated the customer object and removed the postcode. This, in turn, meant that there were no available shipping options.

The reason that this was so hard to reproduce was that a lot of servers automatically set no-store when max-age is 0, or for other reasons. So a lot of the time no-store was set, and therefore I could not reproduce it. But on servers that don't do this, this is 100% reproducible.

Long story short: no-store should be a default directive in wp_get_nocache_headers. The whole point of getting no-cache headers is that you don't want the page cached. And from my point of view especially not in the browser.

Related: #39861

Change History (1)

#1 @johnbillion
3 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Thanks for the report. We're tracking this already in #21938 and fingers crossed we can get it into WordPress 6.3.

Note: See TracTickets for help on using tickets.