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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 19:41:05