在Gatsby中如何根据同级public字段过滤掉GraphQL返回的视频URL?
解决Gatsby中根据同级字段过滤字段的问题
要实现仅当public为true时才返回视频的url字段,直接用GraphQL查询过滤器确实做不到——因为过滤器只能过滤整个节点(比如移除整个playlist项),而不能根据同级字段选择性移除某个子字段。不过我们可以通过Gatsby的createResolvers API在数据解析阶段处理这个逻辑,确保敏感的url不会被包含在页面载荷中。
解决方案:自定义字段解析器
在项目的gatsby-node.js文件中添加以下代码,自定义SanityCourses类型下playlist字段的解析逻辑:
exports.createResolvers = ({ createResolvers }) => { createResolvers({ SanityCourses: { playlist: { resolve: async (source, args, context, info) => { // 获取原始的playlist数据 const originalPlaylist = await context.defaultFieldResolver(source, args, context, info); // 遍历处理每个播放列表项:public为false时移除url字段 return originalPlaylist.map(item => { if (!item.public) { // 解构出除url外的所有字段 const { url, ...rest } = item; return rest; } // public为true时保留完整字段 return item; }); } } } }); };
为什么这个方法有效?
- 这个解析器会在Gatsby构建/开发过程中拦截
playlist字段的原始数据,对每个项进行处理后再返回。 - 当
public为false时,我们通过对象解构移除了url字段,因此最终发送到页面的载荷中不会包含这些敏感链接。 - 你的原GraphQL查询不需要做任何修改,解析器会自动处理数据返回逻辑。
验证效果
运行gatsby develop或gatsby build后,查看页面的返回数据,你会看到public: false的视频项不再包含url字段:
[ { "price": 149, "name": "Master VS Code", "playlist": [ { "title": "Intro", "url": "https://youtu.be/qwertyuiop", "public": true }, { "title": "Principles Part 1", "public": false } ] } ]
为什么不推荐前端处理?
如果只是在React组件中过滤url字段,虽然前端看不到,但这些敏感链接仍然会被包含在Gatsby生成的页面数据载荷中(比如page-data.json文件),用户可以通过查看源码或网络请求获取到,不符合你的需求。而自定义解析器是在数据层处理,从根源上避免了敏感数据被暴露。
内容的提问来源于stack exchange,提问作者André Casal
相关产品推荐
相关产品推荐

