WordPress重定向后Cookie丢失问题技术求助
我在WordPress插件中开发了一个表单,目标是提交时设置Cookie并跳转到指定页面。测试发现提交时Cookie能成功设置,但重定向到站内其他页面后Cookie就丢失了。我试过wp_redirect、wp_safe_redirect、header Location:、window.open()等多种重定向方式,且在重定向前用wp_die($_COOKIE)能看到Cookie,确定问题出在重定向之后。
如何实现表单提交后设置Cookie,且重定向至站内页面时不丢失Cookie,让目标页面能读取这些数据?
现有代码
插件PHP代码
add_action('admin_post_action_configurator_form_submit', 'action_configurator_form_submit'); // 登录用户 add_action('admin_post_nopriv_action_configurator_form_submit', 'action_configurator_form_submit'); // 未登录用户 function action_configurator_form_submit () { // 验证nonce,无效则退出 check_ajax_referer('configurator_form_nonce', 'security'); if(isset($_POST['base_sku'])){ // 存储表单字段为变量 $base_Sku = $_POST['base_sku']; $type = $_POST['type']; $band = $_POST['band']; $polarization = $_POST['polarization']; $gain_Sku = $_POST['gain_sku']; $Az_Pattern = $_POST['azpattern']; $dual_Input = $_POST['dualinput']; $narrowband_Connector = $_POST['connector']; $beamtilt = $_POST['beamtilt']; $null_Fill = $_POST['nullfill']; $heavy_Duty = $_POST['heavyduty']; $invert_Mount = $_POST['invertmount']; $narrowband = $_POST['narrowband']; // 构建SKU $antennaSku = $base_Sku . $type . $band . $polarization . $gain_Sku . $Az_Pattern; $fullSku = $antennaSku . '-' . $dual_Input . '-' . $narrowband . '-' . $narrowband_Connector . '-' . $beamtilt . '-' . $null_Fill . '-' . $heavy_Duty . '-' . $invert_Mount; $cookieValue = array( 'base_Sku' => $base_Sku, 'type' => $type, 'band' => $band, 'polarization' => $polarization, 'gain_Sku' => $gain_Sku, 'Az_Pattern' => $Az_Pattern, 'dual_Input' => $dual_Input, 'narrowband_Connector' => $narrowband_Connector, 'beamtilt' => $beamtilt, 'null_Fill' => $null_Fill, 'heavy_Duty' => $heavy_Duty, 'invert_Mount' => $invert_Mount, 'narrowband' => $narrowband, 'generatedSku' => $fullSku, ); // 根据SKU查找产品 $page = get_page_by_post_name($antennaSku, OBJECT, 'product'); // 设置Cookie,使用方式:$data = json_decode($_COOKIE['antennasNow'], true); unset($_COOKIE['antennasNow']); setcookie('antennasNow', json_encode($cookieValue), time()+3600); if(!empty($page)){ // 找到产品则跳转至产品页 $url = get_permalink($page); redirect_to_antenna_product($url); } else { // 未找到则跳转至 fallback 页面 $url = '/selector-support'; redirect_to_antenna_product($url); } } } function redirect_to_antenna_product($url){ wp_safe_redirect($url); exit(); } function get_page_by_post_name($post_name, $output = OBJECT, $post_type = 'post' ){ global $wpdb; $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", $post_name, $post_type ) ); if ( $page ) return get_post( $page, $output ); return null; } add_action('init','get_page_by_post_name');
表单Action代码
<form action="' . esc_url(admin_url('admin-post.php')) . '" method="post" id="configurator">
解决方案
核心问题分析
admin-post.php位于WordPress的/wp-admin/目录下,默认调用setcookie()时,Cookie的路径会被设为当前脚本所在的目录(即/wp-admin/),这导致只有/wp-admin/路径下的页面能读取到这个Cookie,而前台页面(产品页、/selector-support等)不在该路径下,因此无法读取。
修复步骤
修正
setcookie()的参数,指定Cookie的路径为全站根路径/,并按需设置域名和HTTPS参数:
替换原有的Cookie设置代码:unset($_COOKIE['antennasNow']); setcookie('antennasNow', json_encode($cookieValue), time()+3600);改为:
$cookie_expire = time() + 3600; // 1小时过期 $cookie_path = '/'; // 全站所有路径有效 $cookie_domain = $_SERVER['HTTP_HOST']; // 自动适配当前域名,子域名场景可改为 '.example.com'(注意开头的点) $cookie_secure = is_ssl(); // 若网站启用HTTPS,仅通过HTTPS传输Cookie // 设置Cookie setcookie('antennasNow', json_encode($cookieValue), $cookie_expire, $cookie_path, $cookie_domain, $cookie_secure); // 可选:更新当前请求的$_COOKIE数组,方便后续代码读取 $_COOKIE['antennasNow'] = json_encode($cookieValue);移除不必要的钩子:
get_page_by_post_name是自定义工具函数,不需要挂到init动作上,删除以下代码:add_action('init','get_page_by_post_name');
修复后原理
- 设置
path='/'后,Cookie会在整个网站的所有路径下生效,前台和后台页面都能读取到。 $cookie_domain确保Cookie在当前域名(含子域名,若设置为.example.com)下有效。$cookie_secure提升安全性,避免Cookie在HTTP连接中被传输。
内容的提问来源于stack exchange,提问作者Derek
相关产品推荐
相关产品推荐

