5

I've been trying to make an React site, which would fetch a GET-response from API and print it out to my .html-file. I've managed to fetch the file just right, but i can't access the JSON-data server sends me.

If i use no-cors in my Fetch-request, i get an opaque response containing pretty much nothing, but if i go to Developer tools i can find my data there and read it. If i do use cors, almost same thing. I get an 403-error, but my data is in the browser memory, but my code doesn't print it out. I can find the response from Network in developer tools.

Why does the server give me an error, but still i get my data? And how can i access it, if it's in the browser?

class Clock extends React.Component {
    constructor(props) {
        super(props)
          this.state = {data2: []}
          this.apihaku = this.apihaku.bind(this)
     }

     componentDidMount() {
         this.apihaku(),
         console.log("Hei")
     }

     apihaku () {
         fetch('https://#######/mapi/profile/',
         {method: 'GET', mode:'no-cors', credentials: 'include',
         headers: {Accept: 'application/json'}}
         ).then((response) => {
              console.log(response);
              response.json().then((data) =>{
              console.log(data);
         });
    });
}

render() {
    return <div>
        <button>Button</button>
    </div>
}}

ReactDOM.render(
   <Clock />,
       document.getElementById('content')
)

EDIT: Error images after trying out suggestions

https://i.stack.imgur.com/wp693.png

https://i.stack.imgur.com/07rSG.png

https://i.stack.imgur.com/XwZsR.png

Banana
  • 2,435
  • 7
  • 34
  • 60
Ilmari Kumpula
  • 831
  • 1
  • 10
  • 18
  • can you put this.apihaku() in componentDidMount() and see – Fadi Abo Msalam Mar 11 '18 at 12:14
  • Same errors, it keep giving for this sentence: "response.json().then(data => { console.log("Heih2");" The error message is: Uncaught (in promise) SyntaxError: Unexpected end of input. I can still see the data in console. – Ilmari Kumpula Mar 11 '18 at 12:40
  • _"Why does the server give me an error, but still i get my data?"_ - how could we possibly know that ...? Do you think we have the documentation for `https://#######/mapi/profile/` open here in front of us, because you made it so easy for us to figure out what API you are actually talking about here? _"And how can i access it, if it's in the browser?"_ - by fixing whatever you are doing wrong in talking to this mystery API in the first place, so that it _doesn't_ respond with a status code that signals to the browser "something went wrong, discard the response body" any more. – CBroe Mar 11 '18 at 12:49
  • Sorry about that, but i'm not really sure what kind of info should i provide. I'm not sure are the error messages enough with code or not. The API is for a work project, so i can't really reveal the address. The opaque response that i get from server comes with code 0, but when i go to sources, there is an response 200 OK, where the data is. I'll add some pictures to clarify. – Ilmari Kumpula Mar 11 '18 at 12:56
  • 1
    Start by removing `mode:'no-cors'`. When you use mode: 'no-cors' you’re explicitly specifying that you want the browser to block your frontend code from accessing any data in the response body or headers. See the answers at https://stackoverflow.com/questions/43317967/handle-response-syntaxerror-unexpected-end-of-input/43319482#43319482 and https://stackoverflow.com/questions/42254685/text-response-is-empty-when-using-fetch/42255007#42255007 – sideshowbarker Mar 11 '18 at 22:17
  • I received the answer that it is indeed not possible to use "no-cors". The admin gave me the dev-environment and everything works fine from there. Thank you everyone for help, especially Fadi. – Ilmari Kumpula Mar 12 '18 at 12:14

4 Answers4

4

You're getting an opaque response, because you're using fetch with mode: 'no-cors'. You need to use mode: 'cors' and the server needs to send the required CORS headers in order to access the response.

Richa Goel
  • 41
  • 5
2

Fetch is doing exactly what the documentation says it's supposed to do, from Mozilla:

The fetch specification differs from jQuery.ajax() in two main ways:

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

By default, fetch won't send or receive any cookies from the server, resulting in unauthenticated requests if the site relies on maintaining a user session (to send cookies, the credentials init option must be set). Since Aug 25, 2017. The spec changed the default credentials policy to same-origin. Firefox changed since 61.0b13.

So you need to use CORS, otherwise you get an opaque response (no JSON), and then 403 to me suggests that you haven't authenticated properly. Test your API with Postman, if I had to take a guess I'd say the API isn't sending the cookie because it's a GET request, so no matter how well you set your headers on the client it won't work. Try it as a POST instead. GET requests should really only be used to drop the initial HTML in the browser. I think for your headers use these, include the creds that the API sends and allow the domain to be different.

mode: "cors", // no-cors, cors, *same-origin *=default
credentials: "include", // *same-origin
Community
  • 1
  • 1
Ryan Dines
  • 979
  • 10
  • 18
0

Try this and see where is the error happening i believe in the parsing but lets check and see

fetch(https://#######/mapi/profile/, {
    method: "GET",
    headers: {
       "Content-Type": "application/json"
    },
    credentials: "include"
 })
 .then((response) => {
     console.log(response);
     try {
         JSON.parse(response)
     }
     catch(err){
         console.log("parsing err ",err)
     }
})
.catch((err)=>{
    console.log("err ",err)
});
Banana
  • 2,435
  • 7
  • 34
  • 60
Fadi Abo Msalam
  • 6,739
  • 2
  • 20
  • 25
  • It's still in the same error, does that mean the response is empty? Here are two photos. https://imgur.com/a/8lWUN & https://imgur.com/a/C2ynV – Ilmari Kumpula Mar 11 '18 at 13:04
  • can you do JSON.parse(response) instead of response.json() and console log it – Fadi Abo Msalam Mar 11 '18 at 13:09
  • Yes, now it jumps to this. Apparently it's already parsed? **parsing err SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse () at fetch.then.response (mainfile.js:17) at ** – Ilmari Kumpula Mar 11 '18 at 13:14
  • so is your problem solved now , i have updated my answer if anyone else is facing same thing – Fadi Abo Msalam Mar 11 '18 at 13:22
  • Actually no, it keeps giving me the same (Unexpected token) error. I'm googling at the same time and if i change it to JSON.stringify, i'll get a response. It's just the Status code 0-response and the 200 OK-response with my JSON is only in browser page like in picture 2 on the original post. – Ilmari Kumpula Mar 11 '18 at 13:31
  • can you add the response you are getting , it seems to be the server is not sending correct json format – Fadi Abo Msalam Mar 11 '18 at 13:45
  • are you the one responsible for the backend also ? can you try the api using post man and including the correct headers and check the response – Fadi Abo Msalam Mar 11 '18 at 13:51
  • Yes, i just tried and everything works fine with Postman. The headers & params are the same and I get 200 OK and all the data that i wanted. I tried to get this work first by myself for two days and with Postman i have no problems. I'm not responsible for backend. I work as a tech support and i'm trying to build myself better tools for more efficient working. Picture of it: https://imgur.com/a/chPv3 – Ilmari Kumpula Mar 11 '18 at 14:00
  • can you try the new update i have remove the credentials from the headers as i checked the example on fetch documentation also added the content type and let me know what happens – Fadi Abo Msalam Mar 11 '18 at 14:09
  • Yes, i modified the code and it's back to this opaque-response, which we saw earlier in photos. In Postman, there is one missing parameter which wasn't visible in the picture for **mode: no-cors**. If i try the code with cors enabled, i get 403 Forbidden and the response says _You're not permitted to view this etc._. So, only with no-cors, i do get the 200 OK, like in Postman. I don't understand how come Fetch and Postman work so different.? Parameters are the same. – Ilmari Kumpula Mar 11 '18 at 14:20
0

I had a similar issue, this kind of problem happend when a HTTP port try to send request to a HTTPS endpoint, adding a "mode:'no-cors'" doesn't do what is SOUND doing but rathere when the documentation says.

I fixed the issue by allowing in my API Application for calls from my HTTP port (i'm using a .net 6 as an API in debugging mode, my code look like this https://stackoverflow.com/a/31942128/9570006)

El.K Ibrahim
  • 53
  • 1
  • 8