如何为结账页脚本设置WooCommerce Cookie?地址信息刷新后消失求助
Hey there! Let's break down how to solve both your problems—keeping those shipping county/district/postcode values after a page refresh, and setting proper WooCommerce cookies for them.
Why the Values Disappear on Refresh
Right now, your twzipcode script sets the fields dynamically with JavaScript, but when you refresh the page, the browser resets all form fields to their default state (since there's no saved value to pull from). We need to save those values to a cookie and load them back when the page loads.
Step 1: Update Your JavaScript to Save & Load from Cookies
First, modify your existing script to handle cookie storage and field repopulation. Here's the full updated code:
var $ = jQuery.noConflict(); $(document).ready(function() { // Initialize the twzipcode plugin (adjust selectors to match your setup) $(".woocommerce-shipping-fields").twzipcode({ countySel: ".woocommerce-shipping-fields select[name='county']", districtSel: ".woocommerce-shipping-fields select[name='district']", zipcodeSel: ".woocommerce-shipping-fields input[name='postcode']" }); // Load saved values from cookies when the page loads function loadSavedShippingFields() { var savedCounty = getCookie('shipping_county'); var savedDistrict = getCookie('shipping_district'); var savedPostcode = getCookie('shipping_postcode'); if (savedCounty) { // Set county and trigger change to load district options $(".woocommerce-shipping-fields select[name='county']").val(savedCounty).trigger('change'); // Small delay to ensure twzipcode loads district options before setting it setTimeout(function() { if (savedDistrict) { $(".woocommerce-shipping-fields select[name='district']").val(savedDistrict).trigger('change'); } if (savedPostcode) { $(".woocommerce-shipping-fields input[name='postcode']").val(savedPostcode); } }, 100); } } // Save field values to cookies whenever they change function saveShippingFieldsToCookie() { var county = $(".woocommerce-shipping-fields select[name='county']").val(); var district = $(".woocommerce-shipping-fields select[name='district']").val(); var postcode = $(".woocommerce-shipping-fields input[name='postcode']").val(); // Set cookies with a 1-day expiry (adjust days as needed) setCookie('shipping_county', county, 1); setCookie('shipping_district', district, 1); setCookie('shipping_postcode', postcode, 1); } // Helper functions for cookie management function setCookie(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); } // Match WooCommerce's cookie settings: path=/, SameSite=Lax, secure if HTTPS var secure = window.location.protocol === "https:" ? "; secure" : ""; document.cookie = `${name}=${value || ""}${expires}; path=/; SameSite=Lax${secure}`; } function getCookie(name) { var nameEQ = `${name}=`; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i].trim(); if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length); } return null; } // Run the load function on page ready loadSavedShippingFields(); // Attach save function to field changes $(".woocommerce-shipping-fields select[name='county'], .woocommerce-shipping-fields select[name='district'], .woocommerce-shipping-fields input[name='postcode']") .on('change input', saveShippingFieldsToCookie); });
What This Does:
- Initializes twzipcode: Same as your original script, but with explicit selectors for clarity.
- Loads saved values: When the page loads, it pulls any previously saved county/district/postcode from cookies and fills them into the fields. The small timeout ensures twzipcode has loaded the district options before setting the district value.
- Saves on change: Whenever any of the shipping fields are updated, it saves the new values to cookies immediately.
- Cookie best practices: Matches WooCommerce's default cookie settings (secure for HTTPS, SameSite=Lax, path=/).
Step 2: (Optional) Use WooCommerce's Built-in Cookie Functions for Better Compatibility
If you want to align fully with WooCommerce's cookie system (instead of vanilla JS cookies), you can use PHP via AJAX to set the cookies. Here's how:
First, Add PHP AJAX Handling (in your theme's functions.php or a custom plugin):
// Register AJAX action for saving shipping fields add_action('wp_ajax_save_shipping_fields', 'wc_save_shipping_fields_cookie'); add_action('wp_ajax_nopriv_save_shipping_fields', 'wc_save_shipping_fields_cookie'); function wc_save_shipping_fields_cookie() { // Verify nonce for security if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'woocommerce-checkout')) { wp_send_json_error('Invalid security token'); } // Sanitize and save values to WooCommerce cookies if (isset($_POST['county'])) { wc_set_cookie('shipping_county', sanitize_text_field($_POST['county']), DAY_IN_SECONDS); } if (isset($_POST['district'])) { wc_set_cookie('shipping_district', sanitize_text_field($_POST['district']), DAY_IN_SECONDS); } if (isset($_POST['postcode'])) { wc_set_cookie('shipping_postcode', sanitize_text_field($_POST['postcode']), DAY_IN_SECONDS); } wp_send_json_success('Shipping fields saved to cookie'); } // Prepopulate checkout fields from cookies on page load add_filter('woocommerce_checkout_fields', 'wc_prepopulate_shipping_fields_from_cookie'); function wc_prepopulate_shipping_fields_from_cookie($fields) { // Check if cookies exist and set field defaults if (isset($_COOKIE['shipping_county'])) { $fields['shipping']['shipping_county']['default'] = sanitize_text_field($_COOKIE['shipping_county']); } if (isset($_COOKIE['shipping_district'])) { $fields['shipping']['shipping_district']['default'] = sanitize_text_field($_COOKIE['shipping_district']); } if (isset($_COOKIE['shipping_postcode'])) { $fields['shipping']['shipping_postcode']['default'] = sanitize_text_field($_COOKIE['shipping_postcode']); } return $fields; }
Then, Update the JavaScript's Save Function to Use AJAX:
Replace the saveShippingFieldsToCookie function in the JS with this:
function saveShippingFieldsToCookie() { var county = $(".woocommerce-shipping-fields select[name='county']").val(); var district = $(".woocommerce-shipping-fields select[name='district']").val(); var postcode = $(".woocommerce-shipping-fields input[name='postcode']").val(); // Send values to PHP via AJAX $.ajax({ url: wc_params.ajax_url, type: 'POST', data: { action: 'save_shipping_fields', county: county, district: district, postcode: postcode, security: wc_params.checkout_nonce // Use WooCommerce's checkout nonce }, success: function(response) { console.log(response.data); }, error: function(xhr) { console.error('Error saving shipping fields:', xhr.responseText); } }); }
Why This Is Better:
- Uses WooCommerce's
wc_set_cookiewhich automatically handles secure cookies, SameSite attributes, and expiry times to match WooCommerce's settings. - The
woocommerce_checkout_fieldsfilter prepopulates the fields directly on page load (before JS runs), so users see the saved values immediately even if JS is slow to load.
Final Notes
- Make sure your shipping field names (
county,district,postcode) match exactly what's used in your WooCommerce setup. If your fields have different names (likeshipping_stateinstead ofcounty), adjust the selectors accordingly. - Test this thoroughly on both HTTP and HTTPS sites to ensure cookies work correctly.
- The cookie expiry is set to 1 day in the examples—you can adjust this by changing the
daysparameter in the JSsetCookiefunction, or using a different time value inwc_set_cookie(likeWEEK_IN_SECONDSfor a week).
内容的提问来源于stack exchange,提问作者Hsin

