Ajax购物车 - shopi8 中文建站教程

Ajax购物车

摘要

18 Ajax购物车

先判断问题出现在哪里

传统的 Shopify 购物车体验是:点击加购 -> 页面白屏跳转到 /cart 页面 -> 如果想继续购物,点击浏览器的后退按钮。这种充满摩擦的流程会扼杀用户的连带购买欲。

Ajax购物车的四项 Shopify 检查清单
Ajax购物车的四项 Shopify 检查清单

核心逻辑是:通过 Shopify Storefront Cart API 实现无刷新数据交互。

利用 JavaScript 的 fetch API,在后台默默地向 Shopify 发送加购、更新数量、删除商品的请求。拿到返回的最新购物车 JSON 数据后,使用 DOM 操作或现代前端框架(如 Vue/Alpine.js)局部更新页面右上角的购物车数量角标,并滑出一个精美的抽屉式购物车(Drawer Cart)。

实战步骤

步骤 1:拦截默认的表单提交 (Prevent Default)

操作路径在 product-form.js 中编写监听逻辑

  1. 找到产品页的加购表单(<form action="/cart/add">)。
  2. 监听 submit 事件,并阻止其默认的跳转行为:
    form.addEventListener('submit', async (e) => {
      e.preventDefault();
      const formData = new FormData(form);
      // 执行 Ajax 加购逻辑...
    });

步骤 2:调用 Cart API 添加商品

操作路径使用 fetch 发送 POST 请求

  1. Shopify 提供了极其简单的 Ajax API 接口。
    fetch(window.Shopify.routes.root + 'cart/add.js', {
      method: 'POST',
      headers: { 'X-Requested-With': 'XMLHttpRequest' },
      body: formData
    })
    .then(response => response.json())
    .then(item => {
      console.log('加购成功:', item.title);
      // 触发打开抽屉购物车的事件
      openCartDrawer();
      // 刷新购物车数据
      refreshCart();
    })
    .catch(error => console.error('加购失败:', error));

步骤 3:获取并渲染最新的购物车数据

操作路径调用 GET /cart.js 接口

  1. 加购成功后,需要获取购物车里的所有商品来渲染抽屉。
    fetch(window.Shopify.routes.root + 'cart.js')
    .then(response => response.json())
    .then(cart => {
      // cart.item_count 是总数量,更新右上角角标
      document.querySelector('.cart-count').textContent = cart.item_count;
      
      // 遍历 cart.items 数组,拼接 HTML 字符串,渲染到抽屉的列表中
      renderCartItems(cart.items);
      
      // 更新底部总价
      document.querySelector('.cart-total-price').textContent = formatMoney(cart.total_price);
    });

步骤 4:在抽屉内实现数量修改与删除

操作路径调用 POST /cart/change.js 接口

  1. 在抽屉里,每个商品旁边都有 +- 按钮。
  2. 当用户点击 + 时,获取该商品的 key(购物车中该行的唯一标识)和新的数量。
  3. 发送请求更新数量:
    fetch(window.Shopify.routes.root + 'cart/change.js', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ id: itemKey, quantity: newQuantity })
    })
    .then(...) // 重新调用 refreshCart() 刷新整个抽屉
  4. 删除商品就是将 quantity 设为 0

常见误区与处理方法

误区一:使用纯 JS 拼接复杂的 HTML 导致代码难以维护 (XSS 风险)

规避方法:在上面的步骤 3 中,如果你用原生的 JavaScript 去遍历 cart.items,然后写出像 html += '<div class="item"><h3>' + item.title + '</h3></div>' 这样的代码,这不仅极其痛苦、难以维护,还存在严重的 XSS 跨站脚本攻击风险。现代 Shopify 主题开发,强烈建议使用 Section Rendering API 来代替纯 JS 拼接。 你可以请求 /?section_id=cart-drawer,让 Shopify 服务器直接用 Liquid 渲染好抽屉的 HTML 代码返回给你,前端只需做一次 innerHTML 替换即可。这既保证了代码的整洁,又完美复用了 Liquid 的各种过滤器(如价格格式化、图片裁剪)。

误区二:忽略了 Ajax 请求的并发冲突 (Race Conditions)

规避方法:用户在抽屉里疯狂点击 + 按钮,一秒钟内点了 5 次。由于网络延迟,这 5 个 Ajax 请求到达服务器和返回的顺序可能是错乱的。最终购物车里显示的数量和总价会完全对不上。在处理购物车数量更新时,必须加入防抖(Debounce)机制或请求锁定(Loading State)。 当用户点击 + 后,立刻将整个抽屉加上半透明的 Loading 遮罩,并禁用所有按钮,直到收到服务器的成功响应后,再解除锁定。确保同一时间只有一个购物车修改请求在处理。

误区三:多语言/多货币环境下的路由前缀丢失

规避方法:在写 fetch 请求时,很多新手习惯直接写 fetch('/cart/add.js')。这在单语言店铺没问题。但如果店铺开启了 Shopify Markets,用户切换到了法语版(URL 变成了 yourstore.com/fr)。此时你再请求 /cart/add.js,会报 404 错误或者丢失语言上下文。永远、永远不要硬编码绝对路径! 必须使用 Shopify 注入到全局的路由变量:fetch(window.Shopify.routes.root + 'cart/add.js')window.Shopify.routes.root 会自动带上当前的语言前缀(如 /fr/),确保 Ajax 请求在任何国际化环境下都能精准命中正确的接口。

Ajax购物车从判断到验证的三步执行路径
Ajax购物车从判断到验证的三步执行路径

FAQ

Ajax购物车应该先检查什么?

先在测试主题或测试页面中操作,并保留修改前版本和验证记录。不要同时改很多位置,先记录当前页面和数据,再处理最明确的问题。

需要马上安装新的 Shopify App 吗?

不一定。先判断主题现有功能、后台字段和少量代码能否解决。只有需要持续同步数据或复杂自动化时,再评估 App 的费用、脚本负担和卸载影响。

修改后怎么验证是否有效?

记录修改日期、页面 URL 和改动内容,再用实际页面、移动端、Google Search Console、Bing Webmaster Tools 或 GA4 检查结果。技术修改还要保留测试记录和回滚版本。

哪些情况不建议马上修改?

数据量太少、追踪没有配置、问题还没有复现,或者正在进行大型主题更新时,不建议一次性重做。先把问题拆开,确认影响范围后再改。

下一步阅读

📢 Share this article

Any other questions?

Our professional team is ready to answer your questions.

Was this article helpful to me?

This article is suitable for all merchants and developers who want to learn about Shopify. Whether you are a beginner just starting out with Shopify or an advanced user looking to improve your skills, you will gain practical knowledge and techniques from it. The methods in this article have all been tested and proven in practice and can be directly applied to your projects.

How can we apply the methods described in the article?

Each step in this article comes with detailed instructions and code examples, which you can directly copy and use. It's recommended to try it in a test environment first to confirm the results before applying it to the production site. If you encounter any problems during implementation, feel free to leave a comment or join our discussion group for help; we and our community members will be happy to assist you.

Can the code in the article be used directly?

Yes! All the code examples we provide have been tested and can be used directly in your Shopify theme. Remember to adjust the parameters and styles according to your actual needs. If you encounter any problems, feel free to leave a message for discussion.

How often will new content be updated?

We publish 2-3 high-quality Shopify tutorials and operational tips every week. Follow our WeChat official account or join our discussion group to get the latest content and exclusive resources first.

Can I get help if I encounter a problem?

Of course! You can leave a comment below the article or join our WeChat group to connect with 1000+ Shopify merchants and developers. We'll get back to you as soon as possible.

Ready to get started?

Follow us to get the latest Shopify tutorials and operational tips.

Join the community Contact Us