apollographql/apollo-link

Request has invalid content type header when using XMLHttpRequest polyfill

Opened this issue · 1 comments

Issue details
When using the HttpLink provided by Apollo in combination with the https://www.npmjs.com/package/xmlhttprequest XMLHttpRequest polyfill, the request's content header will be set to text/plain rather than application/json.

This is caused partially due to how Apollo sets request headers and partially how the xmlhttprequest polyfill handles the content-type header; The polyfill only checks for Content-Type (note the capitalization), whereas Apollo sets content-type. In the case the polyfill doesn't find the header with that capitalization, it overwrites it with text/plain.

Relevant issue on the polyfills page: driverdan/node-XMLHttpRequest#183

Overall it's a silly issue, and I'd lean on it being more the fault of the polyfill (due to how in the spec headers are described as case-insensitive), however Apollo also prevents me from overwriting the capitalization of the header in the HttpLink options, even though I can use it to set other headers.

Regardless, I thought I would share my issue and the cause of it in case someone else happens to hit the same problem. e.g. when setting up jest with their react native / expo setup, which is when I hit the problem.

Apollo should probably allow for the overwriting of the content type header, as has been suggested elsewhere (apollographql/apollo-fetch#39).

A simple reproduction

(jest) setup:

const xmlhttprequestPolyfill = require("xmlhttprequest");
const fetchPolifill = require("whatwg-fetch");

global.XMLHttpRequest = xmlhttprequestPolyfill.XMLHttpRequest;
global.fetch = fetchPolifill.fetch;
global.Request = fetchPolifill.Request;
global.Headers = fetchPolifill.Headers;
global.Response = fetchPolifill.Respons;

link:

const link = ApolloLink.from([
    new HttpLink({
        uri: GQL_ENDPOINT,
        credentials: "same-origin"
    })
]);

Then perform any query, and the Content-Type header will be set to text/plain

Seems like the oldest issue in the offending polyfill about this is 8 years old by now 😄. I think we can assume it's not going to get addressed on that side at the very least: driverdan/node-XMLHttpRequest#20

Really the takeaway here is to not use the polyfills in question, and opt-in for node-fetch instead for example. Using node-fetch fitched my issue at least.