Intended outcome:
Header to be:
Content-Type:application/json
Actual outcome:
Content-Type:text/plain;charset=UTF-8
My link configuration:
const link = new HttpLink({
uri: 'http://127.0.0.1:8000',
fetchOptions: {
mode: 'no-cors'
}
});
const cache = new InMemoryCache();
this.client = new ApolloClient({
link,
cache
});
NPM Packages:
{
"name": "to-do",
"version": "0.1.0",
"private": true,
"dependencies": {
"apollo-cache-inmemory": "^1.1.1",
"apollo-client": "^2.0.3",
"apollo-fetch": "^0.6.0",
"apollo-link-http": "^1.1.0",
"graphql": "^0.11.7",
"graphql-tag": "^2.5.0",
"loadash": "^1.0.0",
"react": "^16.1.1",
"react-apollo": "^2.0.1",
"react-dom": "^16.1.1",
"react-scripts": "1.0.17"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
It seems to happen when you use no-cors, even trying to force the header in the fetch options doesn't work
@renatomefi could this have something to do with fetch? In testing I can't replicate this https://github.com/apollographql/apollo-link/pull/283/commits/1201f135ed478ef11b4be2b12f21cd95c55d03cd
@jbaxleyiii Indeed, looks like it's a fetch issue :/
well that stinks!
I run into this problem. Any solution for this one?

@jbaxleyiii I don't think your PR fixed this issue, still sends Content-Type: text/plain;charset=UTF-8.
@joaovpmamede the PR was about testing on apollo-link level, the problem exists inside fetch
so need to ask fetch to fix this first before it can work?
Hi @jbaxleyiii,
i have the same problem, i can't change the header contant-type i use angular1-apollo and i try to applyMiddleware to change header for all request. can you help me please
Why does fetch behave this way? Even though it is a fetch problem, I think this issue should still be open unless a solution is reached or a work-around is found for this, because this is going to kill your adoption rate.
Still having this issue, really annoying...
Hey guys, sorry but I am still having this issue in 1 of 2 different projects I am working on. The one who always fails sends me text/plain;charset=UTF-8 each time is the one that has no-cors enabled.
Is this on the pipeline? Or should we find another way to deal with this for the meantime?
[email protected]
[email protected]
Edit:
I have been reading a little bit and I think this issue is not related to apollo. Apparently when you disable cors, it is required that you only do "simple" requests, but adding the content-type application/json violates this rule. My hypothesis is that the browser system is the one limiting the change of the content-type. I would recommend anyone to not use the no-cors option unless your backend is prepared to accept text/plain... But if you have access to the backend, why not trying to fix the cors instead?
The simplest solution is to use no-cors middleware library to your backend.
This works really well for me.
EDIT: I've posted another, non-hacky solution two comments below this one.
Hi everyone – I've found a solution, at least in Express:
Express app.js:
const bodyParser = require('body-parser');
// ...
app.use('/graphql', bodyParser.text());
app.use('/graphql', (req, res, next) => {
if(typeof req.body === 'string')
req.body = JSON.parse(req.body);
next();
});
bodyParser.text() will append the text/plain to req.bodyReact index.js:
new HttpLink({
// ...
fetchOptions: {
mode: 'no-cors'
}
});
EDIT: I've posted another, non-hacky solution two comments below this one.
@andrao your solution worked for me. Thank you.
@cmcaboy – I've actually found a better solution since, one that doesn't rely on this no-cors hack.
The issue I was having – not sure if this is the case for you – was due to authentication. What I left out of my HttpLink above was that I also had credentials set to true, which attaches cookie data to each GraphQL request.
const httpLink = new HttpLink({
uri: graphQLEndpoint,
credentials: 'include'
});
On my back-end, all requests coming into my GraphQL endpoint were hitting an authentication middleware, which would validate the attached session cookie.
Now, here's the issue. The initial OPTIONS request (alternatively known as the CORS pre-flight request) was failing. That's because – irrespective of the HttpLink credentials setting – cookies do not attach to the OPTIONS request. Therefore all OPTIONS pre-flight requests were unable to pass through authentication, and were thus disabled.
The purpose of the pre-flight request is to check that the server will allow subsequent requests of a certain method type (e.g. POST, PUT, GET, etc.) from the provided origin.
The pre-flight request has 3 headers of import here:
origin, which represents the requesting client domainAccess-Control-Request-Method, which specifies the methods through which the client would like to make further requests (can't recall but this might just be POST for GQL)Access-Control-Request-Headers, which specifies the headers attached to those same further requests-Request- in them.The server then needs to approve the origin (you can reject the request if you don't like the origin), and also approve the methods and headers. This must happen BEFORE any authentication middleware, as the cookie will not be attached to the pre-flight request.
router.use((req, res, next) => {
if (req.method === 'OPTIONS') {
const origin = req.get('origin');
// Where approveOrigin() is a function approving the incoming origin domain.
if (origin && approveOrigin(origin)) {
res.set('Access-Control-Allow-Origin', origin);
res.set('Access-Control-Allow-Methods', req.get('Access-Control-Request-Method'));
res.set('Access-Control-Allow-Headers', req.get('Access-Control-Request-Headers'));
res.set('Access-Control-Allow-Credentials', true);
return res.status(200).send();
}
else {
return next(new Error("Illegitimate origin"));
}
}
next();
});
The server is responsible for attaching to the response the -Allow- headers corresponding to the -Request- headers listed above. The values match:
Access-Control-Allow-Origin == originAccess-Control-Allow-Methods == Access-Control-Request-MethodsAccess-Control-Allow-Headers == Access-Control-Request-HeadersWe return a 200 status with our response headers set. That is all the front-end (client) wants. We also provide a Access-Control-Allow-Credentials header, which permits the front-end to attach cookies to its requests.
If the incoming request is not through the OPTIONS method, we proceed on with next().
Not sure if this will apply to you @cmcaboy, but perhaps someone else will be having the same issue I did.
Any solutions for this ? This issue has been closed but no fix has been provided.
I still get this as my Content-Type :
Content-Type: text/plain;charset=UTF-8
+1
+1
I run into this problem. Any solution for this one?
Did anyone find solution to this? Is it possible to have content-type application/json in request headers when using no-cors?
I came across this issue while implementing Apollo client for my React application. The way I was able to fix it was follow @rohmanhm 's advice and use cors library for node to handle this on my express/graphql endpoint.
So my Apollo client request looks like this after I remove no-cors fetchOptions:
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql'
})
And added this code to express server.js
const cors = require('cors')
app.use('*', cors())
app.use('/graphql', bodyParser.json(), graphqlExpress(buildOptions))
Hope this helps.
Please is there a way to solve this?. files content-type returns text/html.

In case anyone hits this with a similar situation to me (dev on localhost), i.e.
You can solve this by adding "proxy": "http://localhost:8888" to package.json
Then you can just connect to "/graphql" or whatever the API endpoint is, and drop the no-cors option.
TIL!
Most helpful comment
Any solutions for this ? This issue has been closed but no fix has been provided.
I still get this as my
Content-Type:Content-Type:text/plain;charset=UTF-8