Intended outcome:
Apollo recognizes the received headers, sends query, processes response.
Actual outcome:
Apollo ignores received Access-Control-Allow-Origin header, pops error in console, sends the query to the server, ignores the response.
As per packet capture between server & localhost:
Apollo sends:
OPTIONS /graphql HTTP/1.1
Host: meselok.hu
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: /
Server responds:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Max-Age: 86400
Access-Control-Allow-Headers: Content-Type
Content-Length: 0
Content-Type: application/octet-stream
Date: Fri, 13 Apr 2018 11:38:55 GMT
Server: Python/3.6 aiohttp/3.1.2
Error in browser console:
Failed to load http://meselok.hu/graphql: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled
Packet capture shows that Apollo sends the query:
{"operationName":null,"variables":{},"query":"{\n hello\n}\n"}
Server responds:
{"data":{"hello":"World"}}
Data does not load:
Full packet capture & filtered packet capture for the interesting packets attached in zip.
apollo_pcaps.zip
Tested server with a quick python script to make sure it is not the one with the issue:
import requests
headers = {'Origin': 'http://localhost',
'Access-Control-Request-Method': 'POST',
'Access-Control-Request-Headers': 'content-type'}
r = requests.options('http://meselok.hu/graphql', headers=headers)
for header, value in r.headers.items():
print(f'Header: {header} --> {value}')
Outputs:
Header: Access-Control-Allow-Origin --> http://localhost
Header: Access-Control-Allow-Methods --> GET, POST, PUT, DELETE
Header: Access-Control-Allow-Headers --> content-type
Header: Access-Control-Max-Age --> 86400
Header: Content-Length --> 0
Header: Content-Type --> application/octet-stream
Header: Date --> Fri, 13 Apr 2018 14:50:01 GMT
Header: Server --> Python/3.6 aiohttp/3.1.2
As well the browser shows the headers being received:
How to reproduce the issue:
Simple hello-world example to test Apollo with Vue, following this tutorial:
https://www.howtographql.com/vue-apollo/2-queries-loading-links/
The graphql end point for meselok.hu (resolves to 10.0.2.101 in the packet capture) is reachable on http://kennyngston.no-ip.org:9999/graphql .. if needed, if not I'll turn it off.
Code in Vue:
graphql.js:
import gql from 'graphql-tag'
export const HELLO_WORLD = gql`
query { hello }
`
Stuff.Vue:
<template>
<div>
<h4 v-if="loading">Loading...</h4>
{{ stuff }}
</div>
</template>
<script>
import { HELLO_WORLD } from '../constants/graphql'
export default {
name: 'HelloStuff',
data () {
return {
stuff: '',
loading: 0
}
},
apollo: {
stuff: {
query: HELLO_WORLD
}
}
}
</script>
App.Vue:
<template>
<div id="app">
<stuff></stuff>
</div>
</template>
<script>
import Stuff from './components/Stuff'
export default {
name: 'App',
components: {Stuff}
}
</script>
main.js:
import Vue from 'vue'
import App from './App'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import VueApollo from 'vue-apollo'
const httpLink = new HttpLink({
uri: 'http://meselok.hu/graphql'
})
const apolloClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
connectToDevTools: true
})
Vue.config.productionTip = false
Vue.use(VueApollo)
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$loadingKey: 'loading'
}
})
/* eslint-disable no-new */
new Vue({
el: '#app',
provide: apolloProvider.provide(),
components: { App },
template: '<App/>'
})
Version
@kennyngston what was the solution?
Tell us the solution please!
I "solved" it by passing an option:
const client = new ApolloClient({
uri: ...,
fetchOptions: {
mode: 'no-cors',
},
});
If you're coming here because you're stuck in the Apollo Tutorial, this won't be enough to help you because the server they made you deploy with Zeit.now doesn't work (Zeit 2.0 has a new api).
Had a similar issue that was caused by my apollo-server-express
configuration. I had added the cors
package middleware which was being overridden by apollo-server-express
's default cors feature. Had to disable it in the server's configuration with cors: false
. Detailed explanation: https://github.com/expressjs/cors/issues/134#issuecomment-413543241
Had a similar issue that was caused by my
apollo-server-express
configuration. I had added thecors
package middleware which was being overridden byapollo-server-express
's default cors feature. Had to disable it in the server's configuration withcors: false
. Detailed explanation: expressjs/cors#134 (comment)
This was really helpful. You can also specify the origin as opposed to turning the cors off
server.applyMiddleware({ app, cors: { origin: process.env.CLIENT_URL } });
Had a similar issue that was caused by my
apollo-server-express
configuration. I had added thecors
package middleware which was being overridden byapollo-server-express
's default cors feature. Had to disable it in the server's configuration withcors: false
. Detailed explanation: expressjs/cors#134 (comment)
Thank you so much! cors:false
FTW!
Most helpful comment
@kennyngston what was the solution?