简体   繁体   English

Magento添加到购物车问题缓存新产品

[英]Magento add to cart issue on caching new products

I'm having problem with add to cart function in new products widget in the homepage. 我在主页的新产品小部件中添加到购物车功能有问题。 By clicking on “Add to cart” it load /checkout/cart/ page but I receive “The cart is empty!”. 通过点击“添加到购物车”它加载/结帐/购物车/页面,但我收到“购物车是空的!”。 I checked for JS problems but I haven't any error, also in system log. 我检查了JS问题,但我没有任何错误,也在系统日志中。 In cache management, if I disable only BLOCK_HTML cache it works fine; 在缓存管理中,如果我只禁用BLOCK_HTML缓存,它可以正常工作; if I re-enable it I have the problem 如果我重新启用它我有问题

The website is hosted by siteground, actually in cron I have: every 25 min.: php /home/ledsuper/public_html/cron.php > /dev/null every 30 min.: /bin/sh /home/ledsuper/public_html/cron.sh 该网站由siteground托管,实际上我在cron中:每25分钟:php /home/ledsuper/public_html/cron.php> / dev / null每30分钟:/ bin / sh / home / ledsuper / public_html / cron.sh

What is causing the problem? 是什么导致了这个问题? how can I do to try solve? 怎么办才能解决? Thx 谢谢

This problem seems to be that the Cache is storing the "New Products" block, which contains the New Products with a "Add To Cart" Link which contains an old (incorrect) form key 这个问题似乎是Cache正在存储“新产品”块,其中包含带有“添加到购物车”链接的新产品,其中包含旧的(不正确的)表单密钥

What is the form key 什么是表格密钥

This is a mechanism to protect from XSS attack, where a malicious attacker can add stuff to your cart while you're in a different browser tab or even complete an order for you. 这是一种防止XSS攻击的机制,恶意攻击者可以在您使用其他浏览器选项卡时为您的购物车添加内容,甚至可以为您完成订单。 This relies on predictable URLs, because the site will not have access to the actual HTML content in the browser tab where you have your Magento order waiting. 这取决于可预测的URL,因为该站点无法访问您的Magento订单等待的浏览器选项卡中的实际HTML内容。 Everything sent to the Magento store will however submit your cookies and thus use your session. 然而,发送到Magento商店的所有内容都会提交您的Cookie,从而使用您的会话。 By adding a unique key to each form or to each link that generates an action on the server, the URL or form content becomes no longer predictable. 通过为每个表单或在服务器上生成操作的每个链接添加唯一键,URL或表单内容将变得不再可预测。 The form key is stored in the session data and validated upon submission to the server. 表单密钥存储在会话数据中,并在提交给服务器时进行验证。 If they don't match - you get a form key error and the action is not completed. 如果它们不匹配 - 您会收到表单键错误并且操作未完成。

The issue Here 问题在这里

Is that the way the add to cart it is implemented in Magento 1.8 in the New Product widget will generate form key errors, because it will cache a list of new products together with "add to cart" link, which will contain the form key of the user that first requested the page. 这是在新产品小部件中在Magento 1.8中实现的添加到购物车的方式将生成表单键错误,因为它将缓存新产品列表以及“添加到购物车”链接,其中包含表单键首先请求页面的用户。

Why this issue doesn't show up when you're not using caching 当您不使用缓存时,为什么不会出现此问题

When the block is generated, the add to cart link is created in product/widget/new/content/new_grid.phtml using the method $this->getAddToCartUrl which is defined in code/core/Mage/Catalog/Block/Product/Abstract.php which adds the form_key to the url. 生成块时,使用方法$this->getAddToCartUrlproduct/widget/new/content/new_grid.phtml创建添加到购物车链接,该方法在code/core/Mage/Catalog/Block/Product/Abstract.php将form_key添加到url。

Proposed Solutions 提出的解决方案

There are 3 options that I can think of 我能想到3种选择

  1. The simple one is to set the widget cache lifetime to 1, so it doesn't cache it at all. 简单的一点是将窗口小部件缓存生存期设置为1,因此它根本不会缓存它。 (Make sure to refresh all the caches after this change.) The (big) drawback from doing this, is that for every page load there will a call to re-render the block, by loading the collection. (确保在此更改后刷新所有缓存。)执行此操作的(大)缺点是,对于每个页面加载,都会通过加载集合来重新呈现块。
  2. Create a child block just for the add to cart button, which is not cached at all. 仅为添加到购物车按钮创建子块,该按钮根本不缓存。
  3. Change the link by editing product/widget/new/content/new_grid.phtml , and replacing the add to cart button, with a href to the product page, so that instead of adding the product to the cart, you redirect the user to the product page, where they add the product. 通过编辑product/widget/new/content/new_grid.phtml并使用href替换产品页面替换add to cart按钮来更改链接,以便将用户重定向到购物车,而不是将产品添加到购物车。产品页面,他们添加产品。 This is probably the simplest, if you are OK with the workflow. 如果您对工作流程没有问题,这可能是最简单的。

It's best to leave Magento's "Blocks HTML output" cache enabled to improve site performance. 最好让Magento的“阻止HTML输出”缓存启用,以提高网站性能。 You can add a "cache_lifetime" node on your new products block and set it to the minimum allowed (1 second). 您可以在新产品块上添加“cache_lifetime”节点,并将其设置为允许的最小值(1秒)。 In the end, your block code should look something like this: 最后,您的块代码应如下所示:

{{block type="catalog/product_new" name="home.catalog.product.new" alias="product_homepage" template="catalog/product/new.phtml" _productsCount="8" cache_lifetime="1"}}

This will effectively keep the New Products block un-cached while safely keeping all other HTML block elements cached as usual, thus add to cart on caching new products won't have any issue. 这将有效地保持新产品块不缓存,同时安全地保持所有其他HTML块元素像往常一样缓存,因此添加到购物车缓存新产品将不会有任何问题。

I used the answer by Anonymous and modified it to fit my purposes. 我使用Anonymous的答案并修改它以符合我的目的。 This is a kind of an ugly hack but it does work (needs to be put in head.phtml and in a relevant location inside the file): 这是一种丑陋的黑客但它确实有效(需要放在head.phtml和文件中的相关位置):

<script type = "text/javascript"> jQuery(document).ready(function () {
    var fkey = "<?php echo Mage::getSingleton('core/session')->getFormKey(); ?>";
    var onclickold = jQuery(".btn-cart").first().attr("onclick");
    var fkeyold = onclickold.replace(/.*\/form_key\/([a-zA-Z0-9]+)\/.*/,  '$1');
    jQuery(".btn-cart").each(function() {
        var onclick = jQuery(this).attr("onclick");
        if (typeof onclick !== typeof undefined && onclick !== false && onclickold !== fkeyold) {
            var onclick2 = onclick.replace(fkeyold, fkey);
            jQuery(this).attr("onclick", onclick2);
        }
    });
});</script>

Or You can Just use this 或者你可以使用它

<script type = "text/javascript" > jQuery(document).ready(function () {
    var fkey = "<?php echo Mage::getSingleton('core/session')->getFormKey(); ?>";
    var fkeyold = jQuery('[name="form_key"]').val();
    jQuery('[name="form_key"]').val(fkey);
    var action = jQuery('#product_addtocart_form').attr('action');
    var action2 = action.replace(fkeyold, fkey);
    jQuery('#product_addtocart_form').get(0).setAttribute('action', action2);
});</script>
 if (!($formKey = $this->getRequest()->getParam('form_key', null)) || $formKey != Mage::getSingleton('core/session')->getFormKey()) {
                $this->getRequest()->setParams(array('form_key' =>Mage::getSingleton('core/session')->getFormKey()));
     }   

You can make the above code as a module It is worked for me. 您可以将上面的代码作为模块制作它对我有用。 But i did not make it as an module. 但我没有把它作为一个模块。 I directly updated the following file 我直接更新了以下文件

app/code/core/Mage/Checkout/controllers/CartController.php

There is a function 有一个功能

addAction Paste the above code in beginning thats all. addAction将以上代码粘贴到所有内容中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM