2
votes

I'm getting a strange issue that I'm hoping has an extremely simple solution. I'm trying to send a POST request to a server. I have tried this using fetch and using XMLHttpRequest with no luck. My xhr request looks like the following:

var xhr = new XMLHttpRequest();
xhr.open("POST", location);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(obj));

My fetch request looks like the following:

fetch(location, {
      credentials: 'include',
      method: 'post',
      body: JSON.stringify({obj}),
      headers: {
        'Content-Type': 'application/json'
    })
    .then((response) => {
      if (response.ok){
        response = response.json();
      } else {
        response = {};
      }
      window.console.debug(response);
    })
    .then((json) =>{
      window.console.debug(json);
    })
    .catch((error) => {
      window.console.debug(error);
    });

Both of these have the same outcome. If I leave it like above, the credentials don't get sent so it sends an OPTIONS request and I get a 401. My Chrome Network tab Request Headers for the message looks like this:

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:192.168.146.101:8005
Origin:http://localhost:8555
Referer:http://localhost:8555/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36

If I remove the header lines, the content-type is the wrong type (obviously) and so I get a 415. The chrome network tab Request Headers message looks like this:

Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Authorization:Basic YWRtaW46YWRtaW4=
Connection:keep-alive
Content-Length:504
Content-Type:text/plain;charset=UTF-8
Host:192.168.146.101:8005
Origin:http://localhost:8555
Referer:http://localhost:8555/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36

For some reason, when I add a header, it strips the credentials. I've tried sending the encoded user:pass in the header as well like this (but obviously with the real username/password):

var xhr = new XMLHttpRequest();
xhr.open("POST", location);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Basic ' + window.btoa('user:pass');
xhr.send(JSON.stringify(obj));

This is happening in all browsers. Thanks for any and all help!

2
I guess my question is really this: How can I change the content-type without it showing up under Access-Control-Request-Headers and instead just show up where the Content-Type shows up by default? The Postman plugin is able to somehow get it to show up that way, and that seems to be the only solution to this problem. - Bruce

2 Answers

1
votes

The withCredentials attibute only indicates whether or not cross-site Access-Control requests should be made using credentials, I'm not sure if this is what you're looking for https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

did you try this ?

var xhr = new XMLHttpRequest();
xhr.open("POST", location);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(user+':'+pass);
xhr.send(JSON.stringify(obj));
1
votes

I believe I've discovered the issue. The issue is actually that the server responding to the REST APIs is setup to authenticate everything that comes through, including OPTIONS requests. The OPTIONS request is only created if we're trying to do this cross-origin, which I was. The browsers seem to strip authentication from OPTIONS requests, and since the server I'm trying to hit authenticates OPTIONS requests (for some unknown reason), it fails. So I've now tried just WAR'ing up my code and hosting it on the same server and I'm able to get past the authentication issues.