Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo and GraphQL CORS

Running into a frustrating issue with Apollo getting content from a Rails backend. The issue seems to be resolving around the use of CORS in my Apollo project.

Tech

  • apollo-client: 1.9.3
  • graphql: 0.11.7
  • react: 15.6.1
  • react-apollo: 1.4.16

cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins `*`

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

rails is running on port 3001 rails s -p 3001

With this backend you can make curl requests and everything works as expected

Working Curl

curl -X POST -H "Content-Type: application/json" -d '{"query": "{users{first_name}}"}' http://localhost:3001/graphql

This returns back expected data


So this is all pointing to an issue with Apollo and the frontend of the application.

index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import ApolloClient from 'apollo-client';
import { ApolloProvider, createNetworkInterface } from 'react-apollo';

import App from './containers/App.jsx';

const client = new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: 'http://localhost:3001/graphql', <<<<< There is a different endpoint then the standard 'graphql' which is why this is declared
  })
});

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById('root')
);

App.jsx

import React, { Component } from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

class App extends Component {
  render() {
    console.log(this.props);
    return (
      <div>Application</div>
    );
  }
}

const query = gql`
  {
    users {
      first_name
    }
  }
`;

export default graphql(query)(App);

This returns the error

Failed to load http://localhost:3001/graphql: Response to preflight request doesn't pass access control check: 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.

app.jsx (change mode)

const client = new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: 'http://localhost:3001/graphql',
    opts: {
      mode: 'no-cors'
    }
  })
});

This returns the error

Unhandled (in react-apollo) Error: Network error: Network request failed with status 0 - ""`

Looking at the request:

GENERAL

Request URL:http://localhost:3001/graphql
Request Method:POST
Status Code:200 OK
Remote Address:[::1]:3001
Referrer Policy:no-referrer-when-downgrade

RESPONSE HEADERS

Cache-Control:max-age=0, private, must-revalidate Content-Type:application/json; charset=utf-8 Transfer-Encoding:chunked Vary:Origin

REQUEST HEADERS

Accept:*/*
Connection:keep-alive
Content-Length:87
Content-Type:text/plain;charset=UTF-8 <<< I'm wondering if this needs to be application/json?
Host:localhost:3001
Origin:http://localhost:8080
Referer:http://localhost:8080/
User-Agent:Chrome/61

REQUEST PAYLOAD

{query: "{↵ users {↵ first_name↵ __typename↵ }↵}↵", operationName: null}
operationName
:
null
query
:
"{↵  users {↵    first_name↵    __typename↵  }↵}↵"

So what I did to get some sort of response was to install the Chrome Extension Allow-Control-Allow-Origin: *

If mode: 'no-cors' is removed and this extension is active, data can be retrieved.


In looking through the Apollo docs I'm unable to find much on this topic. I tried implementing the Apollo Auth Header but this simply produced the same errors as above.

What in my Apollo code could be causing these errors? And what steps are there to fix the problem?

Searching over GitHub issues and other Google searches are either for much-older versions of Apollo in which issues "have been addressed" or do not work when implemented.

Edit

Adding Ruby on Rails tag just in case there is more configuration needed in Rails. Upon researching the Apollo Client issues found Network error: Network request failed with status 0 - "" This issued was resolved by the OP because of an issue on the backend.

like image 708
wsfuller Avatar asked Oct 09 '17 23:10

wsfuller


1 Answers

Issue was in the cors.rb file

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins `*`

    resource '*',
    headers: :any,
    methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

The issue was origins '*' had backticks instead of quotes

Was also able to remove the opts object in the index.jsx and everything is working as expected

like image 112
wsfuller Avatar answered Sep 27 '22 23:09

wsfuller