You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify自定义应用:如何将Liquid表单数据传入Node运行的JS文件

问题场景

我使用Shopify CLI为Shopify店铺开发注册/登录自定义应用(已遵循官方文档),但Shopify会限制前端Liquid代码发起POST请求的CORS。于是我编写了可通过Node运行的registerCustomer.js文件,用来调用Shopify Admin API创建新客户,但不知道如何将Liquid区块表单中收集的姓名、邮箱、手机号信息传递给该JS文件。

现有Liquid表单代码

<div>
  <h1 data-item="section-heading">
    Register
  </h1>
  <form
    id="contactForm"
    method="POST"
    action="/send-contact">
    <label for="name">Name:</label>
    <input
      type="text"
      name="name"
      placeholder="Enter your name"
      required>
    <label for="email">Email ID:</label>
    <input
      type="email"
      name="email"
      placeholder="Enter your email"
      required>
    <label for="phoneNumber">Phone number</label>
    <input
      type="tel"
      name="phoneNumber"
      placeholder="Enter your phone number"
      required>
    <button type="submit">Submit</button>
  </form>

  <script>
    document.getElementById('contactForm').addEventListener('submit', function(event) {
      event.preventDefault();
      const name = document.querySelector('input[name="name"]').value;
      const email = document.querySelector('input[name="email"]').value;
      const phoneNumber = document.querySelector('input[name="phoneNumber"]').value;

      const data = {
        name: name,
        email: email,
        phoneNumber: phoneNumber
      };

      fetch('/send-contact', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      }).then(function(response) {
        console.log('Contact information sent successfully!');
      }).catch(function(error) {
        console.error('Error sending contact information:', error);
      });
    });
  </script>

</div>

{% schema %}
  {
    "name": "Register Inputs",
    "target": "section",
    "settings": [
      {
        "label": "form",
        "type": "html",
        "id": "register_form"
      }
    ]
  }
{% endschema %}

现有registerCustomer.js代码

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const axios = require("axios")

const customerData = {
  customer: {
      first_name: "Steve",
      last_name: "Lastnameson",
      email: "steve.lastnameson@example.com",
      phone: "+15142546011",
      verified_email: true,
      addresses: [{
          "address1": "123 Oak St",
          "city": "Ottawa",
          "province": "ON",
          "phone": "555-1212",
          "zip": "123 ABC",
          "last_name": "Lastnameso",
          "first_name": "Mother",
          "country": "CA"
      }]
  },
};

async function registerCustomer(customerData) {
  try {
    const response = await axios.post(`https://domain.name.com/admin/api/2022-04/customers.json`, customerData, {
        headers: {
            'X-Shopify-Access-Token': 'password',
            'Content-Type': 'application/json'
        }
      });
    console.log('Customer created:', response);
  } catch (error) {
    console.error('Error creating customer:', error);
  }

}

registerCustomer(customerData);

解决方案:搭建后端中间层接收数据

前端无法直接调用Shopify Admin API(存在CORS限制和密钥泄露风险),也不能直接把数据传给本地Node脚本,需要在自定义应用中添加后端路由作为中间层,流程如下:

  1. 前端表单提交数据到应用的后端路由
  2. 后端路由接收数据后,调用改造后的registerCustomer逻辑创建客户

步骤1:修改前端Liquid的请求目标

将前端fetch的地址替换为应用的后端接口,同时拆分姓名为first_name和last_name(适配Shopify Admin API格式):

<script>
  document.getElementById('contactForm').addEventListener('submit', function(event) {
    event.preventDefault();
    const name = document.querySelector('input[name="name"]').value;
    const email = document.querySelector('input[name="email"]').value;
    const phoneNumber = document.querySelector('input[name="phoneNumber"]').value;

    // 拆分姓名(也可以拆分为两个独立输入框优化体验)
    const nameParts = name.split(' ');
    const firstName = nameParts[0] || '';
    const lastName = nameParts.slice(1).join(' ') || '';

    const data = {
      first_name: firstName,
      last_name: lastName,
      email: email,
      phone: phoneNumber,
      verified_email: true // 根据需求设置是否自动验证邮箱
    };

    // 替换为你的应用代理接口路径
    fetch('/api/register-customer', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    }).then(function(response) {
      if (response.ok) {
        console.log('注册成功!');
        // 可添加跳转或成功提示逻辑
      } else {
        throw new Error('注册失败');
      }
    }).catch(function(error) {
      console.error('注册出错:', error);
    });
  });
</script>

步骤2:改造registerCustomer.js为可复用函数

将原脚本改为接收外部参数的函数,并通过环境变量存储敏感配置:

import axios from "axios";

// 用环境变量存储敏感信息,避免硬编码
const SHOPIFY_SHOP_DOMAIN = process.env.SHOPIFY_SHOP_DOMAIN;
const SHOPIFY_ACCESS_TOKEN = process.env.SHOPIFY_ACCESS_TOKEN;
const API_VERSION = '2022-04';

export async function registerCustomer(customerData) {
  try {
    const response = await axios.post(
      `https://${SHOPIFY_SHOP_DOMAIN}/admin/api/${API_VERSION}/customers.json`,
      { customer: customerData },
      {
        headers: {
          'X-Shopify-Access-Token': SHOPIFY_ACCESS_TOKEN,
          'Content-Type': 'application/json'
        }
      }
    );
    return { success: true, data: response.data };
  } catch (error) {
    console.error('创建客户失败:', error.response?.data || error.message);
    return { success: false, error: error.response?.data || error.message };
  }
}

步骤3:添加后端路由(以Express为例)

在Shopify CLI生成的Node应用中创建路由文件(如routes/register.js),添加POST接口:

import express from 'express';
import { registerCustomer } from '../registerCustomer.js';

const router = express.Router();

// 解析JSON请求体
router.use(express.json());

router.post('/api/register-customer', async (req, res) => {
  const customerData = req.body;
  
  // 可选:添加数据验证逻辑,比如检查邮箱格式、手机号合法性
  if (!customerData.email || !customerData.email.includes('@')) {
    return res.status(400).json({ error: '请输入有效的邮箱地址' });
  }

  const result = await registerCustomer(customerData);
  if (result.success) {
    res.status(201).json({ message: '客户创建成功', customer: result.data.customer });
  } else {
    res.status(400).json({ error: result.error });
  }
});

export default router;

然后在server.js中挂载该路由:

import registerRouter from './routes/register.js';
app.use(registerRouter);

关键注意事项

  • 环境变量安全:在项目根目录创建.env文件,存储SHOPIFY_SHOP_DOMAIN和SHOPIFY_ACCESS_TOKEN,Shopify CLI会自动加载该文件。
  • 应用代理配置:在Shopify Partner后台的应用设置中,配置代理路径(如/api/*),确保前端请求能转发到你的应用服务器。
  • 权限配置:确保你的应用已申请write_customers权限,否则调用Admin API会返回权限错误。

内容的提问来源于stack exchange,提问作者Rishi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:16:58