Cookie JS脚本在子域及Acquia环境失效:代码/Drupal/Acquia原因?
Hey there! 作为JS新手能边做边摸索已经很棒啦~ 咱们来一步步解决你的Cookie问题,先从最明显的小错误入手,再搞定跨域的难题。
首先,修复代码里的语法错误(这是web.example.com反复显示横幅的关键原因!)
看你的getCookie函数里这一行:
var ARRcookies=document.cookie.split(";";
这里少了一个闭合的括号),应该改成:
var ARRcookies=document.cookie.split(";");
这个语法错误会导致getCookie函数直接失效,浏览器读不到已经设置的cookie-accept Cookie——哪怕你在web.example.com上已经点了“Continue”,页面加载时还是会判定Cookie不存在,重新弹出横幅。先把这个修复了,web.example.com的问题大概率就能解决。
然后,解决Acquia域(example.prod.acquia-sites.com)无法设置Cookie的问题
浏览器有个严格的Cookie规则:你只能给当前页面的主域或其子域设置Cookie,不能跨完全不同的主域(比如从.acquia-sites.com给.example.com设置Cookie)。所以在Acquia的编辑站上,你的代码没法设置.example.com的Cookie,自然也没法记住用户是否接受了Cookie。
我们可以修改代码,让它根据当前访问的域名动态调整Cookie的设置规则:
- 如果当前域名是
.example.com的子域(包括web.example.com、store.example.com等),继续使用domain=.example.com,保证这些站点之间共享Cookie。 - 如果当前域名是Acquia的域(example.prod.acquia-sites.com),就设置一个仅在该域下有效的Cookie,用来记录用户的选择,这样编辑站就不会反复弹出横幅了。
修改后的完整代码(带注释)
/* 修复并增强的Cookie读写函数 */ function getCookie(c_name) { var i, x, y, ARRcookies = document.cookie.split(";"); // 修复了语法错误 for (i = 0; i < ARRcookies.length; i++) { x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("=")); y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1); x = x.replace(/^\s+|\s+$/g, ""); if (x === c_name) { return unescape(y); } } // 如果没找到Cookie,返回null而不是undefined,判断更清晰 return null; } function setCookie(c_name, value, exdays) { var exdate = new Date(); exdate.setDate(exdate.getDate() + exdays); var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()); var cookieDomain = ""; // 获取当前页面的域名 var currentDomain = window.location.hostname; // 判断当前域名是否属于.example.com的子域 if (currentDomain.endsWith(".example.com") || currentDomain === "example.com") { cookieDomain = ";domain=.example.com"; } // 判断是否是Acquia的编辑域 else if (currentDomain === "example.prod.acquia-sites.com") { // 不设置domain,默认就是当前域,Cookie仅在该域有效 cookieDomain = ""; } // 拼接Cookie字符串,加上path=/保证全站有效 document.cookie = c_name + "=" + c_value + cookieDomain + ";path=/"; } jQuery(document).ready(function($) { function displayCookieAccept() { var cookieAccepted = getCookie('cookie-accept'); // 现在判断更准确,因为getCookie返回null或't' if (cookieAccepted !== 't') { var cookieBox = $('<div class="cookie-accept"></div>'); var cookieText = '<p>This site uses cookies. By continuing to browse this site you are agreeing to our use of cookies. <a href="#" id="accept-cookie">Continue</a> or <a href="/home/privacy-policy" id="privacy">Find out more</a>.</p>'; $(cookieBox).html(cookieText); $('body').prepend(cookieBox); $(cookieBox).slideDown('fast'); $('#accept-cookie').click(function(e) { // 阻止默认跳转行为(避免点击#后页面跳顶部) e.preventDefault(); setCookie('cookie-accept', 't', 1825); $(cookieBox).hide(); }); } } displayCookieAccept(); });
额外的小优化说明
我还加了两个细节让代码更健壮:
- 在
getCookie函数末尾返回null,这样判断Cookie是否存在时更清晰,不会出现undefined的模糊情况。 - 在点击“Continue”时加上了
e.preventDefault(),防止点击链接时页面意外跳转到顶部。
这样修改后:
- 所有
.example.com的子域(包括web.example.com)依然能正常共享Cookie,完全不会破坏现有功能。 - 在Acquia的编辑域(example.prod.acquia-sites.com)上,用户点击“Continue”后,会设置一个仅属于该域的Cookie,页面刷新后就不会再显示横幅了。
内容的提问来源于stack exchange,提问作者complik8
相关产品推荐
相关产品推荐

