melange-community / melange-fetch

Fetch bindings for Melange
MIT License
203 stars 53 forks source link

Response headers is empty #18

Closed jetaggart closed 6 years ago

jetaggart commented 6 years ago

I'm unable to get response headers. I'm not sure if I'm using the library wrong or if there's a bug.

Here is my code attempting to get the authorization header:

          let payload = Js.Dict.empty();
          Js.Dict.set(payload, "username", Js.Json.string(values.username));
          Js.Dict.set(payload, "password", Js.Json.string(values.password));
          Js.Promise.(
            Fetch.fetchWithInit(
              "http://localhost:8080/login",
              Fetch.RequestInit.make(
                ~method_=Post,
                ~body=Fetch.BodyInit.make(Js.Json.stringify(Js.Json.object_(payload))),
                ~headers=Fetch.HeadersInit.make({"Content-Type": "application/json"}),
                (),
              ),
            )
            |> then_(response =>
                 Js.log(Fetch.Headers.has("Authorization", Fetch.Response.headers(response))) |> resolve
               )
          );

The has function returns false. If I log the response from headers I get an empty js object I believe.

Here is a screenshot of the successful request:

screen shot 2018-07-02 at 2 08 35 pm
glennsl commented 6 years ago

This sounds like a CORS issue, though the screenshot suggests it's not even a cross-origin request. bs-fetch is a very thin binding to fetch, with not much room for issues like this to originate in bs-fetch itself. See fi you can get it to work with fetch in plain javascript (just use the javascript console). If you can't, the problem certainly isn't with bs-fetch.

jetaggart commented 6 years ago

I switched to getting what I needed from the body and it worked fine, so I don't think it's a CORS issue. What's interesting is I can't seem to access any headers. I should be able to see any one of those headers in the response, correct? When I log Fetch.Response.headers(response) I get an empty js object, and asking if that type has any of the above headers, it returns false. Admittedly, I'm new to reason/bs so I could have a misunderstanding of how it should work.

I also tried to use httpbin.org and got the same issue.

          let payload = Js.Dict.empty();
          Js.Dict.set(payload, "username", Js.Json.string(values.username));
          Js.Dict.set(payload, "password", Js.Json.string(values.password));
          Js.Promise.(
            Fetch.fetchWithInit(
              "https://httpbin.org/post",
              Fetch.RequestInit.make(
                ~method_=Post,
                ~body=Fetch.BodyInit.make(Js.Json.stringify(Js.Json.object_(payload))),
                ~headers=Fetch.HeadersInit.make({"Content-Type": "application/json"}),
                (),
              ),
            )
            |> then_(resp =>
                 if (Fetch.Response.status(resp) == 200) {
                   Js.log2("Headers", Fetch.Response.headers(resp));
                   Js.log2("Content-Length: ", Fetch.Headers.has("Content-Length", Fetch.Response.headers(resp)));
                   resolve(resp);
                 } else {
                   setError(Some("Incorrect username/password"));
                   setSubmitting(false);
                   reject(Not_found);
                 }
               )

Screenshots:

screen shot 2018-07-03 at 12 01 45 pm screen shot 2018-07-03 at 12 03 21 pm

BTW, thanks for the library, it's working great for everything else!

glennsl commented 6 years ago

Sorry for the late response. I've been away on holiday for a few days.

Whether CORS or not, my advice is the same: See if you can get it to work in plain JavaScript. If you can't, it's not an issue with bs-fetch, and you might have an easier time searching for the solution elsewhere. If you can get it to work, it should be pretty easy to identify what's different between the two versions. There really isn't much that can go wrong in bs-fetch itself, and especially not something that'll return a proper and valid value rather than just undefined.

jetaggart commented 6 years ago

No worries, I'll try that out and see if I can figure out what's going on, thanks for the response!