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

React使用fetch获取Shopify博客Feed失败,如何解决?

问题描述

我有一套曾成功获取WordPress Feed的代码,但无法在Shopify上实现同样效果。我已在Shopify中创建私有应用,并将访问令牌放入请求头,但React端返回如下CORS错误:

Access to fetch at 'https://example.com/blogs/blog.atom' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

使用的代码如下:

const mediumRssFeed = "https://example.com/blogs/blog.atom";
const MAX_ARTICLES = 99;

const [articles, setArticles] = useState();

useEffect(() => {
  const loadArticles = async () => {
    fetch(mediumRssFeed, { headers: {"X-Shopify-Access-Token": "XXX", Accept: "application/json" }, crossDomain: true })
      .then((res) => res.json())
      .then((newArticles) => newArticles.slice(0, MAX_ARTICLES))
      .then((articles) => setArticles(articles))
      .catch((error) => console.log(error));
  };
  loadArticles();
}, [MAX_ARTICLES]);

请问如何将Shopify商店的博客集成到React项目中?


解决方案

核心问题分析

你当前的问题有两个关键矛盾:

  1. Shopify博客的.atom Feed是XML格式,不是JSON,直接用res.json()解析会报错
  2. Shopify的公开Feed接口不支持前端跨域请求,且私有应用令牌不能直接暴露在前端代码中(存在密钥泄露风险)

方法一:后端代理(生产环境推荐)

搭建后端代理接口,由后端发起请求获取Shopify博客数据,再返回给前端,既避开CORS限制,又保护令牌安全。

示例Node.js代理代码(Express框架)

const express = require('express');
const axios = require('axios');
const xml2js = require('xml2js');
const app = express();

// 代理接口
app.get('/api/shopify-blog', async (req, res) => {
  try {
    // 从Shopify获取XML格式的博客Feed
    const feedResponse = await axios.get('https://example.com/blogs/blog.atom', {
      headers: {
        'X-Shopify-Access-Token': '你的私有应用令牌'
      }
    });

    // 将XML转换为JSON格式
    const parser = new xml2js.Parser({ explicitArray: false });
    parser.parseString(feedResponse.data, (parseErr, result) => {
      if (parseErr) throw parseErr;
      // 提取文章数据并截取指定数量
      const articles = result.feed.entry.slice(0, 99);
      res.json(articles);
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(4000, () => console.log('代理服务运行在 http://localhost:4000'));

React端修改后的请求代码

const proxyUrl = "http://localhost:4000/api/shopify-blog";
const [articles, setArticles] = useState();

useEffect(() => {
  const loadArticles = async () => {
    fetch(proxyUrl)
      .then((res) => res.json())
      .then((articles) => setArticles(articles))
      .catch((error) => console.log(error));
  };
  loadArticles();
}, []);

方法二:使用Shopify Storefront API

如果私有应用有权限,可调用Shopify Storefront API直接获取结构化的JSON博客数据,同样通过后端代理发起请求:

后端代理中的Storefront API请求示例

app.get('/api/shopify-blog', async (req, res) => {
  try {
    // GraphQL查询语句,按需调整返回字段
    const query = `
      {
        blogByHandle(handle: "blog") {
          articles(first: 99) {
            edges {
              node {
                title
                excerpt
                publishedAt
                url
                featuredImage {
                  url
                }
              }
            }
          }
        }
      }
    `;

    const response = await axios.post('https://example.com/api/2024-07/graphql.json', { query }, {
      headers: {
        'X-Shopify-Storefront-Access-Token': '你的Storefront令牌'
      }
    });

    // 提取并格式化文章数据
    const articles = response.data.data.blogByHandle.articles.edges.map(edge => edge.node);
    res.json(articles);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

方法三:no-cors模式(仅临时调试)

如果只是临时测试,可设置mode: 'no-cors'绕过CORS,但这种方式只能获取不透明响应,无法解析内容,绝对不推荐生产环境使用:

fetch(mediumRssFeed, { 
  mode: 'no-cors',
  headers: {"X-Shopify-Access-Token": "XXX"}
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:05:24