0

I'm using React 16 and the fetch-interceptor library. I have this in a file called src/interceptors/fetch.js ...

import fetchIntercept from 'fetch-intercept';

const unregister = fetchIntercept.register({

  response: function (response) {
    console.log("\n\ncalled function!");
    console.log("body:" + response.body);

    // Do something with the response
    console.log(response.headers);
    console.log("header: " + response.headers.get('Refresh-Token') );
    if (response.ok && 'Refresh-Token' in response) {
      const token = response['Refresh-Token'];
      console.log("saving " + token);
      sessionStorage.setItem('token', token)
    }
    return response;
  },

});

In my src/App.js component, I include it like so

import { unregister } from "./interceptors/fetch.js";

but when I make a fetch call, I can't seem to get any headers. The console line

console.log("header: " + response.headers.get('Refresh-Token') );

prints out

header: null

despite the fact in my Chrome Devtools, I see

.   Access-Control-Allow-Origin: http://localhost:3000
.   Allow: POST, OPTIONS
.   Content-Length: 196
.   Content-Type: application/json
.   Date: Tue, 05 Jul 2022 14:48:49 GMT
.   Referrer-Policy: same-origin
.   Refresh-Token: f7c622e042b38a9fc2c594a914c2fe38ffa8fb53
.   Server: WSGIServer/0.2 CPython/3.9.1
.   Vary: Accept, Origin
.   X-Content-Type-Options: nosniff
.   
X-Frame-Options: DENY

under the "Response Headers" section. I get the same result in consolelog if I try and query other types of headers, e.g. "Content-Type". What's the right way to get my header value?

Edit: In response to the answer given, the output of the console log is

.   {content-length: '180', content-type: 'application/json'}
.   content-length: "180"

.  content-type: "application/json"

which is odd that only those two headers are showing up, because from Chrome devtools, there are many more headers (notice the content-length matches)

enter image description here

Dave
  • 15,639
  • 133
  • 442
  • 830
  • 1
    If you are doing a CORS request (eg. localhost:3000 calls localhost:8080) you don't have access to all headers, you need to explicitly allow that with additional header. Check this answer for more details https://stackoverflow.com/a/44816592/976509 – vl4d1m1r4 Jul 10 '22 at 21:55
  • If I'm reading what you intended, the answer says " If you control the server, you can return custom information in the response body instead of headers". I do control the server but does this mean it is impossible to access custom response headers using fetch? I find that hard to believe. – Dave Jul 11 '22 at 17:05
  • 1
    I was more referring to this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers. You would need to allow that header, `Refresh-Token` to be allowed so that fetch API can read it. – vl4d1m1r4 Jul 11 '22 at 18:40
  • Did you try to use `debugger` in your code? You can simply put `debugger` and open the dev tools and it will stop right on that line you need to check. – Anton Jul 11 '22 at 22:06

2 Answers2

0

The Response object's headers does have a headers.get() method, so you are correctly calling that.

Your 'Refresh-Token' in response and response['Refresh-Token'] expressions don't look correct, but as you say, you are seeing your null value before that.

It is difficult to say why that is returning null without seeing the exact response, but one way you can debug this is by getting the entries() of your headers, and convert them to a plain object via Object.fromEntries(). This might be easier to inspect in your console.

See this example -

const unregister = fetchIntercept.register({
  response: function (response) {
    console.log("response:", response);
    const headersObj = Object.fromEntries([...response.headers.entries()]);
    console.log(headersObj);

    return response;
  }
});

Otherwise, for the other parts of your code, to check if a header exists: useresponse.headers.has(key) instead of key in response.headers, and to get the header, use response.headers.get(key) instead of response[key].

romellem
  • 5,792
  • 1
  • 32
  • 64
  • I added some details to my question to show the output of your console.log suggestion and the actual response that comes back in devtools. – Dave Jul 09 '22 at 21:27
0

If you go through the specs of fetch API on MDN, you will see that it has a fixed set of headers that are readable by the scripts for CORS requests, and to allow more headers you will need to add them to the allow list using Access-Control-Expose-Headers(assuming you have access to the server).

The Access-Control-Expose-Headers response header allows a server to indicate which response headers should be made available to scripts running in the browser, in response to a cross-origin request.

It's not like these headers can't be accessed at all, but the browser will respect the specs and not allow reading non-allowed headers by scripts running on the page. That's why you can see the headers in the network tab but your script is not able to access the custom headers.

Adarsh Singh
  • 146
  • 5