1

I'm very new to react, and new ish to nodeJS. I'm trying to test how to pull json data from my nodeJS webservices and render it in react. I'm only at the test stage but am struggling to understand what this issues is. I can get content from demo jobs json resource with:

let url = "http://codepen.io/jobs.json";
let iterator = fetch(url);
  iterator
    .then(response => response.json())
    .then(post => alert(post.jobs[3].company_name));
  } 

but my own JSON resource is at http://localhost:8888 - so I've learned I need to set no-cors in the header to allow cross site resources, so interpretation for my own resource, I have tried:

let url = "http://codepen.io/jobs.json";
let iterator = fetch(url, {mode: 'no-cors'});
  iterator
    .then(response => response.json())
    .then(post => alert(post.jobs[3].company_name));
  } 

But this gives me an error of: "Uncaught (in promise) SyntaxError: Unexpected end of input" on the resonse.json() line.

Any ideas? Over all I would really appreciate some wider react code to take the jobs list, add it to the component state and then render the list - along the lines of:

componentDidMount() {
  let url = "http://codepen.io/jobs.json";
  let iterator = fetch(url, {method: 'GET', mode: 'no-cors'});
  iterator
    .then(response => response.json())
    .then(post => alert(post.jobs[3].company_name));
} 

render() {        
    return(
        <div>
            <div>Items:</div>
            <div>{this.state.items.map etc</div>
        </div>  
    );
}
quamrana
  • 37,849
  • 12
  • 53
  • 71
Andrew
  • 53
  • 1
  • 7

2 Answers2

3

the response you are getting from codepen has the type: 'cors' but you are providing mode:no-cors, the server needs to send the required CORS headers in order to access the response.

enter image description here

componentDidMount() {
   let url = "https://codepen.io/jobs.json";
   let iterator = fetch(url, {method: 'GET', mode: 'cors'});
   iterator
     .then(response => {
       console.log('sss', response)
       return response.json();
     })
     .then(post => alert(post.jobs[3].company_name));
   }

render() {        
  return(
      <div>
        <div>Items:</div>
           <div>{this.state.items.map etc</div>
        </div>  
    );
}
parwatcodes
  • 6,669
  • 5
  • 27
  • 39
  • Many thanks p0k8! I think this comes from my limited understanding of CORS! So I guess the CORS header flag needs to match. So if I switch this over to my http://localhost:8888, i need to write a matching header (cors or no-cors?). My nodeJS webservice is at the moment just a super basic query against postgres: ending in an output line: res.json(content); I don;t suppose you coudl advise how to change the header here? :) Thanks again! – Andrew Feb 20 '17 at 11:18
  • i guess you need to do nothing, cors is allowded to provide the access to another domain. codepen has enabled cors, which means anyone can request for the data, and there is a lot more to understand about CORS https://www.maxcdn.com/one/visual-glossary/cors/ – parwatcodes Feb 20 '17 at 11:27
  • if some another domain application is trying to hit your `localhost:8888`, you have to use the `cors` middleware to allow the the access Basically our app checks the `Origin` Header Type if it doesn't match to our domain `localhost:8888`, then it will throw an cors error – parwatcodes Feb 20 '17 at 11:32
  • Thanks again pok8. I added the following to my Express webservice response which sorted it.: // Website you wish to allow to connect res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); // Request methods you wish to allow res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // Set to true if you need the website to include cookies in the requests res.setHeader('Access-Control-Allow-Credentials', true); – Andrew Feb 20 '17 at 11:53
  • yes you have to do that, or there is a `cors` package in npmjs.com, install it and use as middleware, some sort of small codes, the type of codepen is cors so mode should be -- mode: 'cors' – parwatcodes Feb 20 '17 at 11:54
3

Just to make the code in the comments of the answer a little clearer. pOk8 identified the issue. In my layman terms, I needed to change the headers of my localhost web service to enable the react fetch to work. Here is what I added to me nodeJS express service headers:

// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);

Hopefully that makes sense.

Andrew
  • 53
  • 1
  • 7