【问题标题】:Shopping cart: Cookies only holding 2 - 5 items购物车:饼干只能容纳 2 - 5 件商品
【发布时间】:2013-07-10 08:59:01
【问题描述】:

对于具有 javascript 技能的人来说,这可能是一个简单的解决方案(轻松 +200 声望)。

问题演示:http://shoppingcart-bthub.blogspot.com/ 只需将所有商品添加到购物车并单击刷新即可查看 cookie 的问题。

一切正常,除了处理添加到购物车的商品的 cookie 的代码部分。出于某种原因,它仅包含 2 -5 个项目,具体取决于浏览器:

Google Chrome - 仅包含 2 件商品(购物车中的所有其他商品在页面重新加载后都会消失)

Firefox - 总共 4 项

Safari - 4

互联网浏览器 - 5

演示中的javascript: http://shopppingcart.googlecode.com/files/simplecart.js

上面 javascript 链接中用于处理 cookie 的部分:

    /*** data storage and retrival ****/ 
/* load cart from cookie */ 
me.load = function () {
var me = this;
 /* initialize variables and items array */
me.items = {};
me.total = 0.00;
me.quantity = 0;

 /* retrieve item data from cookie */
if( readCookie('simpleCart') ){
var data = unescape(readCookie('simpleCart')).split('++');
for(var x=0, xlen=data.length;x<xlen;x++){
var info = data[x].split('||');
var newItem = new CartItem();   
if( newItem.parseValuesFromArray( info ) ){
newItem.checkQuantityAndPrice();

/* store the new item in the cart */
 me.items[newItem.id] = newItem;
 }
 }
 }
 me.isLoaded = true;
};

/* save cart to cookie */
me.save = function () {
var dataString = "";
for( var item in this.items ){
dataString = dataString + "++" + this.items[item].print();
}
createCookie('simpleCart', dataString.substring( 2 ), 30 );
};

测试完整的实时代码:

要获取包含所有代码的完整实时模板,请在 blogger.com 上打开一个免费博客并在此处下载 XML 模板以上传到博客:http://www.bloggermint.com/2011/05/shopping-cart-blogger-template/ 免费下载在左侧边栏中。还请按照该页面上的说明在 blogger.com 中使用它

【问题讨论】:

  • 嗨循环,我刚刚在 IE10 和 Chrome 中测试了 simplecart.js(第一个)。似乎我无法重现您的错误。我创建了 10 个名称很长的项目,并将每个项目的 10 个单位添加到购物车中。我的 simplecart cookie 长度为 1136 字节。我建议 2 件事:1. 验证您没有 cookie 限制/权限问题,2. 分享您的 html/js,也许错误在您的代码中。
  • 我正在使用的购物车的演示可以在这里找到:shoppingcart-bthub.blogspot.in 页面上的所有 .js 和 HTML 内容都与我网站上的完全相同。这个网站上的错误也是一样的。只需添加所有项目并单击刷新,您就会看到错误。
  • 我很想在我的帖子中发布所有的 HTML,但是因为它在 blogger.com 平台上,所以它非常庞大。希望该演示站点的查看源代码和检查元素将有助于缩小我遇到的错误。您还有什么需要,请告诉我。
  • 我很好奇你是如何在不知道创建购物车并与 js 一起工作的 HTML 的情况下测试 js 文件的?我希望有 js 技能的人可以简单地查看处理 cookie 的 js 的一小部分(我帖子中的第一个代码)并了解为什么它只持有有限的数量。除了 js 如何处理 cookie 之外,我看不出这个 bug 与其他任何东西有什么关系?因此,该错误发生在刷新浏览器后。不管怎样,谢谢你的尝试。我将在上面发布创建购物车的 HTML(尽管它在演示站点上可见,但它会更容易)。
  • 我创建了一个与 simplecart 配合使用的简单 html 页面。我建议你分享 html+js 是因为你提到了你在那里的一些定制,而不是因为我不能自己写一个示例 :)

标签: javascript variables cookies session-cookies shopping-cart


【解决方案1】:

在我看来,问题与 4K cookie 大小限制有关。
您的 shopppingcart 代码试图将所有项目数据存储在 simpleCart cookie 中,但是当此类数据大于 4K 时,即使它们显示在购物车中,项目也不会存储到 cookie 中,因此当页面重新加载后那些项目消失了。
以网站 http://shoppingcart-bthub.blogspot.in/ 为例,特别是“Sony VAIO 笔记本电脑”项目的 HTML 标记:

<table border="1" style="width: 660px;">
    <tbody>
        <tr>
            <th class="item_thumb" id="thumb" width="45%"><img border="0" src="http://3.bp.blogspot.com/-LcQD--Bb_YE/TeDI44AmUsI/AAAAAAAACBw/K4IJZE2CpMY/s1600/sony+vaio.JPG"></th>
            <td>
                <input class="item_add" type="button" value="Add to Cart" id="s1">
            </td>
        </tr>
        <tr>
            <th><b>Item Name</b></th>
            <td class="item_name">Sony VPCEE42FX 15.5" 2.30GHz 500GB VAIO Laptop</td>
        </tr>
        <tr>
            <th><b>Price</b></th>
            <td class="item_price">$610.00</td>
        </tr>
        <tr>
            <th><b>Description</b></th>
            <td class="item_Description">
            The VPCEE42FX is big enough to be useful, but small 
            enough to be portable. With 500GB of hard drive space, youll have to work hard 
            to fill up the memory. The 15.5 HD resolution screen and AMD Mobility Radeon HD 
            graphics card ensure that youll see crisp, fast action, even when youre watching 
            DVDs on the DVD drive. And at under six pounds, the laptop is easy to pack up 
            and haul with you.
            </td>
        </tr>
        <tr>
            <th><b>Available Stock</b></th>
            <td>2 more available</td>
        </tr>
    </tbody>
</table>

将此产品添加到购物车后,simpleCart cookie 将包含以下字符串:

id=c10||thumb=%3Cimg%20border%3D%220%22%20src%3D%22http%3A//3.bp.blogspot.com/-LcQD--Bb_YE/TeDI44AmUsI/AAAAAAACBw/K4IJZE2CpMY/ s1600/sony+vaio.JPG%22%3E%0A||name=Sony%20VPCEE42FX%2015.5%22%202.30GHz%20500GB%20VAIO%20Laptop||price=610||description=%20VPCEE42FX%20is%20big% 20enough%20to%20be%20useful%2C%20but%20small%20enough%20to%20be%20%0Aportable.%20With%20500GB%20of%20hard%20drive%20space%2C%20youll%20have%20to%20work%20hard%20to %20%0Afill%20up%20the%20memory.%20The%2015.5%20HD%20resolution%20screen%20and%20AMD%20Mobility%20%0ARadeon%20HD%20graphics%20card%20ensure%20that%20youll%20see%20crisp%2C% 20fast%20action%2C%20even%20%0Awhen%20youre%20watching%20DVDs%20on%20the%20DVD%20drive.%20And%20at%20under%20six%20pounds%2C%20the%20%0Alaptop%20is%20easy%20to %20pack%20up%20and%20haul%20with%20you.||quantity=1

如您所见,似乎所有类名以item_ 开头的&lt;td&gt; 元素都存储在cookie 中。
Chrome 开发者工具显示此 cookie 的大小为 828 字节。
因此,可以添加到购物车的商品数量是可变的,并且取决于每个商品数据的长度(名称、描述等)。
那么,您可以做些什么来避免这个问题呢?

  1. 将项目 HTML 标记减少到最少,例如通过删除 item_thumbitem_Description 元素。
  2. 修改simplecart.js代码中的addToCart方法,通过存储更少的信息来减少cookie的长度(详见下文)。
  3. 修改simplecart.js 代码中的createCookiereadCookieeraseCookie 函数以使用local storage 而不是cookie 来存储项目数据(查看this page 以获取代码示例,或者下面再举一个例子)。

例如,为了避免在 cookie 中存储“thumb”和“Description”项字段,您可以修改 addToCart 方法如下:

ShelfItem.prototype.addToCart = function () {
  var outStrings = [],valueString;
  for( var field in this ){
    if( typeof( this[field] ) != "function" && field != "id" ){
      valueString = "";

      //console.log(field);
      switch(field){
        case "price":
          if( this[field].value ){
            valueString = this[field].value;
          } else if( this[field].innerHTML ) {
            valueString = this[field].innerHTML;
          }
          /* remove all characters from price except digits and a period */
          valueString = valueString.replace( /[^(\d|\.)]*/gi , "" );
          valueString = valueString.replace( /,*/ , "" );
          break;
        case "image":
          valueString = this[field].src;
          break;
        case "thumb":
        case "Description":
        case "description":
          /* don't store "thumb" and "description" in the cookie */
          break;
        default:
          if( this[field].value ){
            valueString = this[field].value;
          } else if( this[field].innerHTML ) {
            valueString = this[field].innerHTML;
          } else if( this[field].src ){
            valueString = this[field].src;
          } else {
            valueString = this[field];
          }
          break;
      }
      outStrings.push( field + "=" + valueString );
    }
  }
}

如果浏览器支持,更好的方法是使用 localStorage,否则使用 cookie 作为后备:

function supports_html5_storage() {
  try {
    return 'localStorage' in window && window['localStorage'] !== null;
  } catch (e) {
    return false;
  }
}

function createCookie(name,value,days) {
  if (supports_html5_storage()) {
    if (value == '') {
      eraseCookie(name);
    } else {
      window.localStorage.setItem(name, JSON.stringify(value));
    }
  } else {
    if (days) {
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
  }
}

function readCookie(name) {
  if (supports_html5_storage()) {
    return window.localStorage.getItem(name);
  } else {
    var ca = document.cookie.split(';');
    var nameEQ = name + "=";
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  }
}

function eraseCookie(name) {
  if (supports_html5_storage()) {
    window.localStorage.removeItem(name);
  } else {
    createCookie(name,"",-1);
  }
}

使用localStorage时,我们也可以毫无问题地存储thumbdescription字段(因为我们有5 Mb的空间),因此我们可以进一步修改ShelfItem.prototype.addToCart函数这样:

  ...
  case "thumb":
  case "Description":
  case "description":
    if (!supports_html5_storage()) break;
  ...

【讨论】:

  • 非常感谢!这些信息非常有帮助。我使用模板中的一个简单的 CSS 代码从每篇文章中删除了所有描述,并且成功了!您能否将其重新编码为显示所有内容的位置,减去每个 cookie 的描述?显然,我不需要将描述放在 cookie 中。但我想要拇指,当它被转移到饼干上时,它是一个小拇指,所以我希望它留下来。如果您为我这样做并且有效,我将奖励您 +200。
  • 我这里只是猜测,因为我不知道js代码,但是如果我删除: case "image": valueString = this[field].src;休息; case "thumb": 从你上面的代码中,它仍然会显示图像缩略图并且仍然是一个有效的工作代码,对吗?
  • 我为您的回答@Enzino 添加了一个赞成票,因为答案非常明智。我喜欢学习和获得知识,这个答案对此有所帮助,也直接解决了这个问题。只需要回答我上面的问题即可奖励您选择的答案和+200。
  • 对不起@Enzino 另一个答案是:vsenik 打败了你。他已经重新编写了 js 以不将描述添加到 cookie 中。我希望我能因为你提供的这些无价的信息和知识而奖励你,但我必须是不可或缺的,我希望你能理解。
  • 哇,非常感谢@Enzino 你太棒了!我会用这个。你很有帮助,知识渊博。我敢打赌,你甚至可以弄清楚如何使用 Paypal 和 Google Wallet 让购物车结账。这就是我现在正在做的事情。希望我有你做的知识!再次感谢您花这么多时间在这方面并提供如此清晰和完整的答案,这些答案远远超出了问题的范围!也希望我能给你一些回报。你是如此的付出,如此难得的人才。
【解决方案2】:

您似乎在黑暗的房间里抓黑猫,而猫不在。

所以我做了什么:

  1. 获取http://shopppingcart.googlecode.com/files/simplecart.js
  2. http://wojodesign.com/simpleCart/获取html
  3. 用你的替换 simplecart.js。

我发现了什么:

  1. 当您从文件系统打开 html 页面时,您就拥有了所拥有的
  2. 如果你把它放在服务器上(在我的例子中是本地的 apache 实例),那么一切正常

2 集。

您试图在 cookie 中放入大量信息。 像这样修改打印功能的简单方法

CartItem.prototype.print = function () {
    var returnString = '';
    for( var field in this ) {
      if( typeof( this[field] ) != "function" && field !="description") {
        returnString+= escape(field) + "=" + escape(this[field]) + "||";
      }
    }
    return returnString.substring(0,returnString.length-2);
  };

你真的需要cookie中的所有项目字段吗?

【讨论】:

  • 其实这个js是为Blogger.com平台编写的。我有一个博客模板,其中这个 js 运行良好,除了 cookie 在购物车中仅包含 2-5 件商品。情况一直如此,因此在他们的演示网站上:shoppingcart-bthub.blogspot.in 同样的问题。购物车正在工作,但创作者没有解决这个问题(在这个版本中)。我需要修复这个版本,因为我的购物车网站周围的所有东西都是非常定制的,我会失去几个月的工作。它甚至看起来不像是同一个演示,但所有的基本代码都是一样的。
  • 以防我不够清楚。本页的购物车:wojodesign.com/simpleCart 与本页完全不同的购物车(同一个团队打造):shoppingcart-bthub.blogspot.in 第二页的js是我用的(shopppingcart.googlecode.com/files/simplecart.js)是与第一页不同的版本。由于上个月进行的极端自定义,我无法在第一次使用 js。
  • 好的。我有一些解决方法。尝试修改打印功能。原始的一个提供了很多信息。
  • 我想要cookie中除描述外的所有项目字段,可以吗?
  • 是的。我添加打印功能来回答。
猜你喜欢
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 2015-06-01
  • 2018-11-29
  • 2020-01-14
  • 2015-07-26
相关资源
最近更新 更多