将Apollo Server更新到2+后,我的React项目抛出:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8081/graphql. (Reason: CORS request did not succeed).[Learn More]
onLogin err: Error: Network error: NetworkError when attempting to fetch resource.
这仅在手机上发生,而不在台式机上发生。两个设备都通过Wifi连接。同时,subscriptions can't establish a connection
同时运行我的React Native项目。
我不确定在这里还有什么要说的。。。在过去的几个小时里,我一直在疯狂,尽管他们说在所有平台上都应该使用相同的代码,但并不能做到正确。
服务器代码:
import http from 'http';
import express from 'express'
const requestIp = require('request-ip');
import { ApolloServer, makeExecutableSchema } from 'apollo-server-express'
const typeDefs = require('./typeDefs').default
const resolvers = require('./resolvers').default
import getUser from './getUser';
const app = express();
const schema = makeExecutableSchema({ typeDefs, resolvers })
const PORT = 8081;
// const corsOptions = {
// origin: '*',//'http://localhost:' + PORT + '/graphql',
// credentials: true
// }
const server = new ApolloServer({ cors: corsOptions, typeDefs, resolvers,
uploads: false,
subscriptions: {
path: "/subscriptions",
onConnect: (connectionParams, webSocket, context) => {
console.log("onConnect subscriptions server")
if (connectionParams.authToken) {
console.log('subsctiptions')
return getUser(connectionParams.authToken, "user")
.then(user => {
if (!user) {
return null
}
// console.log('found user -> ' + user.id)
// console.log(context)
return {
user: user,
};
})
.catch(error => {
console.log('error index.js server onConnect auth: ' + error)
});
}
}
},
context: async (req) => {
if (req.connection) {
if (req.req) {
req.connection.context.clientIp = req.req.clientIp
}
return req.connection.context;
} else {
const token = req.req.headers.authorization || "";
return { token } ;
}
},
});
app.use('/graphql', (req, res, next) => {
const typeDefs = require('./typeDefs').default
const resolvers = require('./resolvers').default
const schema = makeExecutableSchema({ typeDefs, resolvers })
server.schema = schema
next();
})
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);
httpServer.listen(PORT, () => {
console.log(` Server ready at http://localhost:${PORT}${server.graphqlPath}`)
console.log(` Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`)
})
客户代码:
import App from './App';
import About from './About'
import ApolloClient from 'apollo-client'
import { ApolloProvider } from 'react-apollo';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { split } from 'apollo-link'
import { HttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'
const httpLink = new HttpLink({
// fetchOptions: {
// mode: 'no-cors',
// },
//uri: 'http://46.101.146.22:8081/graphql'
uri:'http://localhost:8081/graphql'
});
const authLink = setContext(async (req, { headers }) => {
const token = await localStorage.getItem('@jwt:key');
return {
...headers,
headers: {
authorization: token ? `Bearer ${token}` : null,
},
};
});
const linkConcated = authLink.concat(httpLink)
const wsLink = new WebSocketLink({
uri: 'ws://localhost:8081/subscriptions',
// fetchOptions: {
// mode: 'no-cors',
// },
options: {
reconnect: true,
connectionParams: () => (
new Promise((resolve,reject) => {
localStorage.getItem("@jwt:key")
.then(token => {
if (token) {
console.log('token: ' + token)
resolve({
"authToken": token
})
}
else {
console.log('no token: ' + token)
resolve({
"authToken" : ""
})
}
})
})
)
}
})
const link = split(
({query}) => {
const { kind, operation } = getMainDefinition(query)
return kind === 'OperationDefinition' && operation === 'subscription'
},
wsLink,
linkConcated,
)
const client = new ApolloClient({
link: link,
cache: new InMemoryCache()
});