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脚本,需要在自定义应用中添加后端路由作为中间层,流程如下:
- 前端表单提交数据到应用的后端路由
- 后端路由接收数据后,调用改造后的
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
相关产品推荐
相关产品推荐

