如何在脱离iframe的独立应用中使用Shopify GraphQL
Shopify独立应用GraphQL请求无响应修复方案
故障根因
该问题是嵌入式应用转独立运行时的常见适配问题,核心原因如下:
- 嵌入式模式下Shopify App Bridge会自动为所有GraphQL请求注入当前会话的
X-Shopify-Access-Token鉴权头,独立运行时无自动注入能力,请求缺少鉴权信息被Shopify拦截 - 嵌入式模式下GraphQL请求默认走Shopify内置代理绕过跨域限制,独立运行时前端直接调用Shopify Admin API会触发浏览器CORS跨域拦截,请求无返回导致一直卡在加载状态
- 脱离Shopify Admin iframe后,当前页面没有继承有效登录会话,即便手动加了过期token也会被鉴权拒绝
修复步骤
1. 补充独立应用OAuth鉴权逻辑
独立应用打开时首先校验本地是否存储了有效的Shopify access token,无有效token时先跳转到Shopify OAuth授权流程,完成授权后将token、所属shop域名存入本地存储。
2. 调整Apollo客户端配置,自动注入鉴权头
修改你项目中的Apollo客户端初始化代码,添加中间件自动把本地存储的access token加到请求头:
// 老版本react-apollo配置示例 import { ApolloClient } from 'apollo-client'; import { createHttpLink } from 'apollo-link-http'; import { setContext } from 'apollo-link-context'; import { InMemoryCache } from 'apollo-cache-inmemory'; const httpLink = createHttpLink({ // 走自有后端代理,不要直接请求Shopify API uri: '/api/shopify/graphql-proxy', }); const authLink = setContext((_, { headers }) => { const accessToken = localStorage.getItem('shopify_access_token'); return { headers: { ...headers, 'X-Shopify-Access-Token': accessToken || '', } } }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache() });
3. 新增后端代理接口绕过CORS限制
Shopify Admin API不支持前端直接跨域调用,需要在你的应用后端新增代理接口,转发前端的GraphQL请求到对应Shopify站点的API端点,Node.js Express示例如下:
const fetch = require('node-fetch'); app.post('/api/shopify/graphql-proxy', async (req, res) => { // 从请求头/查询参数取当前店铺域名 const shopDomain = req.headers['x-shopify-shop-domain'] || req.query.shop; const accessToken = req.headers['x-shopify-access-token']; try { const shopifyRes = await fetch(`https://${shopDomain}/admin/api/2024-07/graphql.json`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Shopify-Access-Token': accessToken }, body: JSON.stringify(req.body) }); const result = await shopifyRes.json(); res.json(result); } catch (err) { res.status(500).json({ errors: [{ message: err.message }] }); } });
完成以上配置后,你原有的查询组件代码不需要修改即可正常运行。
内容的提问来源于stack exchange,提问作者ArunKumar
相关产品推荐
相关产品推荐

