Reputation: 1840
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
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.
Upvotes: 5
Views: 8609
Reputation: 1840
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
Upvotes: 7