React SSR应用调用Wiki.js GraphQL接口时遭遇CORS错误求助
React SSR 调用 Wiki.js GraphQL 接口时的 CORS 错误解决方案
问题场景
我在基于 React SSR 的应用中调用 Wiki.js 的 GraphQL 接口获取数据时,遭遇了 CORS 错误。相关代码及错误信息如下:
实现代码
App.js
const client = new ApolloClient({ uri: 'https://example-wiki.herokuapp.com/graphql', cache: new InMemoryCache(), headers: { Authorization: 'Bearer exampleToken1234abc', }, });
api.js
import { useQuery, gql } from '@apollo/client'; const ALL_PAGES_QUERY = gql` query PageQuery { pages { list { id title tags } } } `; export const getAllPages = () => { const { loading, error, data } = useQuery(ALL_PAGES_QUERY); return { loading, error, data, }; };
错误信息
Access to fetch at 'https://example-wiki.herokuapp.com/graphql' 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.
我已尝试 Wiki.js 官方讨论区提供的解决方案,但未生效。
可行解决方案
1. 服务端配置反向代理(SSR 场景首选)
利用 SSR 应用的服务端作为中间层,由服务端发起请求到 Wiki.js 接口,规避浏览器跨域限制,同时也更安全(避免 token 暴露在前端)。
以 Express 为例,在服务端代码中添加代理配置:
// server.js(SSR服务端入口) const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); // 配置Wiki.js GraphQL代理 app.use('/wiki-graphql', createProxyMiddleware({ target: 'https://example-wiki.herokuapp.com', changeOrigin: true, pathRewrite: { '^/wiki-graphql': '/graphql' }, // 把Authorization header放在服务端配置,避免前端暴露 headers: { Authorization: 'Bearer exampleToken1234abc' } })); // 其他SSR相关启动代码...
修改前端 Apollo Client 的请求地址为代理路径:
// App.js const client = new ApolloClient({ uri: '/wiki-graphql', // 替换为服务端代理路径 cache: new InMemoryCache(), // 移除前端的Authorization header,改为由服务端代理携带 });
2. 配置 Apollo Client 使用 no-cors 模式(仅限特殊场景)
如果你的业务不需要读取接口返回的数据,可以强制请求使用 no-cors 模式,但这种模式下浏览器会返回无法解析的 opaque 响应,仅适合不需要处理响应的场景:
// App.js const client = new ApolloClient({ uri: 'https://example-wiki.herokuapp.com/graphql', cache: new InMemoryCache(), headers: { Authorization: 'Bearer exampleToken1234abc', }, fetch: (uri, options) => { return fetch(uri, { ...options, mode: 'no-cors' }); } });
3. 重新确认 Wiki.js 的 CORS 配置
再次检查 Wiki.js 的 config.yml(或对应环境变量)中的 CORS 配置,确保参数正确并重启服务:
cors: enabled: true origin: "http://localhost:3000" # 明确指定你的前端地址,生产环境避免用* methods: GET,HEAD,PUT,PATCH,POST,DELETE credentials: true
如果是 Heroku 部署,需确认环境变量是否正确映射了上述配置项(比如 WIKI_CORS_ENABLED=true、WIKI_CORS_ORIGIN=http://localhost:3000 等)。
内容的提问来源于stack exchange,提问作者Rehan Zia
相关产品推荐
相关产品推荐

