Shopify GraphQL API创建商品时商品描述语法错误问题
使用Node.js+GraphQL调用Shopify API创建商品时的HTML描述语法错误问题
我用Node.js结合GraphQL调用Shopify API创建商品,在处理带HTML元素的商品描述时遇到问题。流程是:PHP端先移除描述里的style属性,再用htmlentities处理后,把body_html字段传给Node.js;Node.js端用html-entities的decode方法解码,转义双引号后构建productCreate的GraphQL查询。多数情况正常,但部分商品创建时报错:
Create Simple ProductError: syntax error, unexpected invalid token (""") at [9, 25]
GraphQL查询代码
const { decode } = require('html-entities'); static create_simple_product(data){ let decoded_desc = decode(data.body_html); const prodQuery = ` mutation { productCreate( input: { title: "${data.title}", productType: "${data.product_type}", vendor: "${data.vendor}", status:${statusData}, bodyHtml: "${decoded_desc.replace(/"/g, '\\"')}", tags:"${typeof data.tags !== 'object' ? "" : data.tags}", handle:"${data.handle}", seo: {description: "${data.seo_description}", title: "${data.seo_title}"}, published:true } media: {originalSource: "${data.images[0]}", mediaContentType: IMAGE, alt: "${data.title}"} ) { product { id title bodyHtml description vendor productType createdAt updatedAt handle status totalInventory totalVariants tracksInventory variants(first: 50) { nodes { id inventoryItem { id } title price compareAtPrice createdAt updatedAt sku barcode weight weightUnit inventoryQuantity inventoryManagement position image { src id altText } } } options(first: 50) { id name position optionValues { name hasVariants id } } images(first: 100, sortKey: POSITION) { edges { node { id src altText height width } } } media(first: 100) { edges { node { id ... on MediaImage { id image { src } } } } } } userErrors { field message } } } `; return prodQuery; }
PHP端请求体代码
$output_desc_prod = preg_replace('/<([^>]+)(\sstyle=(?P<stq>["\'])(.*)\k<stq>)([^<]*)>/iUs', '<$1$5>', $get_product_data->descriere_produs); $product_description = htmlentities($output_desc_prod); $data_sf_prod = array( "api_key" => $site_data->api_key, "server_key" => $site_data->server_key, "title" => $get_product_data->nume_produs, "body_html" => $product_description, "vendor" => strtolower($site_data->den_site), "status" => "draft", "product_type" => "", "tags" => "", "images" => $array_images_final, "seo_description" => $getMetaData->md, "seo_title" => $getMetaData->mt, "price" => $priceSelector, "sku" => $get_product_data->cod_produs, "handle"=> $get_product_data->slug_produs, "barcode" => $get_product_data->ean === "" ? null : $get_product_data->ean, "weight" => 1, "weight_unit" => "", "compare_at_price" => $priceCompareSelector );
问题原因及解决办法
核心问题
手动拼接GraphQL查询字符串时,仅转义双引号无法覆盖所有特殊字符(比如换行、反斜杠、单引号等),部分未处理的字符会破坏查询的语法结构,导致报错。
正确解决方案:使用GraphQL变量
完全抛弃手动拼接字符串的方式,改用GraphQL变量传递参数,Shopify的GraphQL客户端会自动处理所有字符转义,彻底避免语法错误。
重构后的代码示例:
const { decode } = require('html-entities'); static create_simple_product(data){ let decoded_desc = decode(data.body_html); // 定义查询所需的变量 const variables = { input: { title: data.title, productType: data.product_type, vendor: data.vendor, status: statusData, bodyHtml: decoded_desc, tags: typeof data.tags !== 'object' ? "" : data.tags, handle: data.handle, seo: {description: data.seo_description, title: data.seo_title}, published: true }, media: [{ originalSource: data.images[0], mediaContentType: 'IMAGE', alt: data.title }] }; // 带变量占位符的查询模板 const prodQuery = ` mutation productCreate($input: ProductInput!, $media: [CreateMediaInput!]!) { productCreate( input: $input, media: $media ) { product { id title bodyHtml description vendor productType createdAt updatedAt handle status totalInventory totalVariants tracksInventory variants(first: 50) { nodes { id inventoryItem { id } title price compareAtPrice createdAt updatedAt sku barcode weight weightUnit inventoryQuantity inventoryManagement position image { src id altText } } } options(first: 50) { id name position optionValues { name hasVariants id } } images(first: 100, sortKey: POSITION) { edges { node { id src altText height width } } } media(first: 100) { edges { node { id ... on MediaImage { id image { src } } } } } } userErrors { field message } } } `; // 返回查询模板和变量,发送请求时一起传递 return { query: prodQuery, variables }; }
额外优化
PHP端可以简化处理流程:移除style属性后,直接将HTML内容传给Node.js,不需要再用htmlentities转义。因为GraphQL变量会自动处理所有特殊字符,多余的转义步骤反而可能引入额外问题。
内容的提问来源于stack exchange,提问作者Pruteanu Alexandru
相关产品推荐
相关产品推荐

