You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为结账页脚本设置WooCommerce Cookie?地址信息刷新后消失求助

Fixing Shipping Field Loss on Refresh & Setting WooCommerce Cookies for Twzipcode

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=/).

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_cookie which automatically handles secure cookies, SameSite attributes, and expiry times to match WooCommerce's settings.
  • The woocommerce_checkout_fields filter 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 (like shipping_state instead of county), 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 days parameter in the JS setCookie function, or using a different time value in wc_set_cookie (like WEEK_IN_SECONDS for a week).

内容的提问来源于stack exchange,提问作者Hsin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:04:21