升级Rails至7.0.4后@vue/apollo-composable useQuery无请求触发
Rails 7.0.4升级后Apollo Client无GraphQL请求问题排查
环境信息
- 原技术栈:
- Rails 6.1.7
- GraphQL Ruby 2.0.19
- 前端依赖:
@apollo/client3.7.10@vue/apollo-composable^4.0.0-beta.4- Vue ^3.2.47
- Vite(
vite_rails)提供JS模块(Rails 6时期已使用)
- 核心问题:升级Rails到7.0.4后,前端调用
useQuery无GraphQL请求产生,前后端无报错;Postman可正常发起请求,Firefox/Chrome/Edge多浏览器均无请求输出。
排查与修复步骤
1. 验证CORS配置变化
Rails 7对CORS默认规则做了收紧调整,检查config/initializers/cors.rb:
- 确认
origins字段包含前端域名(开发环境可临时设为origins "*"测试) - 确保
resource块明确开放GraphQL端点,示例:Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins "http://localhost:3000" # 替换为你的前端实际域名 resource "/graphql", headers: :any, methods: [:get, :post, :options] end end
2. 检查Content Security Policy(CSP)头
Rails 7默认启用更严格的CSP,可能阻止Apollo发起请求:
- 打开浏览器控制台安全标签,查看是否有CSP相关警告
- 在
config/initializers/content_security_policy.rb中,确保connect_src包含前端或GraphQL端点域名:Rails.application.config.content_security_policy do |policy| policy.default_src :self, :https policy.connect_src :self, :https, "http://localhost:3000" # 同域名请求需确保包含:self end - 开发环境可临时设置
policy.default_src :self, :https, :unsafe_eval, :unsafe_inline快速验证是否为CSP导致。
3. 确认Apollo Client配置正确性
检查前端Apollo Client的端点配置:
import { ApolloClient, InMemoryCache } from '@apollo/client'; import { createApolloProvider } from '@vue/apollo-option'; const client = new ApolloClient({ uri: '/graphql', // 跨域场景需写完整URL,如"http://localhost:3000/graphql" cache: new InMemoryCache(), }); const apolloProvider = createApolloProvider({ defaultClient: client, });
- 确保
@vue/apollo-composable的provideApolloClient已正确注入Vue应用实例。
4. 处理Rails 7的CSRF保护变更
Rails 7对POST请求的CSRF校验更严格,GraphQL POST请求需携带CSRF Token:
- 前端请求头中添加
X-CSRF-Token,示例:const csrfToken = document.querySelector('meta[name="csrf-token"]').content; const client = new ApolloClient({ uri: '/graphql', cache: new InMemoryCache(), headers: { 'X-CSRF-Token': csrfToken, }, });
5. 开启Apollo Client错误监听
添加错误监听捕获静默报错:
client.onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { graphQLErrors.forEach(({ message, locations, path }) => console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`) ); } if (networkError) console.log(`[Network error]: ${networkError}`); });
- 查看浏览器控制台是否有隐藏的错误信息。
内容的提问来源于stack exchange,提问作者janosrusiczki
相关产品推荐
相关产品推荐

