Axios - Request header content-type was not present in the Access-Control-Allow-Headers list - ElasticSearch

Viewed 460

I'm new to a lot of this technology, but I think I've diagnosed my issue and need some help. I've seen numerous posts on SO regarding this issue, but none have worked, though they have helped me diagnose issue.

I believe the issue is when I send the Header Content-Type w/ my pre-flight w/ Axios, it fails. This is possibly due to lower/case upper case? The error has lower case, but I tried both on the server without luck.

Basically, if I don't specify any header and Axios uses json as content-type, it works, but as soon as I specify Content-Type my pre-flight fails (even though I think post would work..).

Here is the elasticsearch.yml

cluster.name: "docker-cluster"
network.host: 0.0.0.0
http.cors.enabled : true
http.cors.allow-origin: "*"
http.cors.allow-methods: OPTIONS,HEAD,GET,POST,PUT,DELETE
http.cors.allow-headers: X-Requested-With,X-Auth-Token,Content-Type,Content-Length
#http.cors.allow-credentials: true

Here is my JS that I'm testing BTW w/ an Office Add-In solution in Visual Studio 2017 which I think is using IE as a browser.

Main Func:

var URL = "https://elasticsearch:9200/users/_search"
const data = {
    "query": {
        "match": {
            "name": "freesoftwareservers"
        }
    }
};
Do_Axios('get', URL, data, null, false)
Do_Axios('post', URL, data, null, false)

Do_Axios:

async function Do_Axios(method, URL, data, headers, withCredentials) {
    return axios({
        method: method,
        url: URL,
        withCredentials: withCredentials,
        //contentType: 'application/json', // does nothing
        //data: JSON.stringify(data), //Causes urlformencoded which is wrong
        data: data, //caues type to be json and I get error
        headers: {
            //"Content-Type": "application/json"
        },
    })
        .then(function (response) {
            console.log("Axios " + method + " response:");
            console.log(response)
            return response;
        })
        .catch(function (error) {
            console.log(error);
        });
}

Note: I can get/post if I comment out //data but then the post doesn't run my query. If I uncomment data then Axios uses urlformencoded but that doesn't work.

For now, I've been able to search API via urlformencoded queries, but I'd like to fix my ability to POST correctly to resolve future errors. I'm unsure if issue should be pointed to Axios or Elasticsearch if I open a request.

1 Answers

Well, I finally figured it out. I wonder how many of the other posts I read have similar issues... anyway, the issue was w/ my NGinX proxy server. No better way to learn about CORS then to setup an API and make CORS requests via IE! Without the below, I was still able to post w/ POSTMAN to the same URL which hit my nginx server, but the call from Axios/IE/JS Evironment failed.

I found these snippets and this was the magic that needed added to my "regular" configuration:

proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;

https://gist.github.com/sahilsk/b16cb51387847e6c3329

Here is my code as it stands, cleaned up but generic atm:

Note: I pass axios because I can't figure out how to get my Webpack to transform/polyfill my funcs in seperate js files. But I can declare axios in the main func and pass it and then I can move my funcs into separate files as needed for organization. There is likely a better way to do without passing axios and configuring webpack

Main Func:

var username = "freesoftwareservers"
var ipv4 = "192.168.1.255"
var showhelp = "false"
await Do_AddUserToES(axios,username, ipv4, showhelp)
Get_UserFromES(axios,username)
var index = "users"
var query = {
    query: {
        match: {
          "username": username
        }
    }
};
Get_PostQueryToES(axios,query, index)

Funcs:

function Do_Axios(axios, method, URL, data, headers, withCredentials) {
    return axios({
        method: method,
        url: URL,
        withCredentials: withCredentials,
        data: data,
        headers: headers,
    })
        .then(function (response) {
            console.log("Axios " + method + " response:");
            console.log(response)
            return response;
        })
        .catch(function (error) {
            console.log(error);
        });
}

function Get_ESURL(Bool_Search, Bool_Doc, Bool_Update, Opt_Index, Opt_IndexKey) {
    var ESUrl = "https://elasticsearch:9200"
    var ESSearch = "/_search"
    var ESDoc = "/_doc"
    var ESUpdate = "/_update"
    var ReturnURL = ESUrl
    if (Opt_Index != undefined) { ReturnURL = ReturnURL + "/" + Opt_Index }
    if (Bool_Search == true) { ReturnURL = ReturnURL + ESSearch }
    if (Bool_Doc == true) { ReturnURL = ReturnURL + ESDoc }
    if (Bool_Update == true) { ReturnURL = ReturnURL + ESUpdate }
    if (Opt_IndexKey != undefined) { ReturnURL = ReturnURL + "/" + Opt_IndexKey }
    console.log("ReturnURL:" + ReturnURL)
    return ReturnURL;
}

function Do_AddUserToES(axios, username, ipv4, showhelp) {
    var adduser = {
        "username": username,
        "ipv4": ipv4,
        "showhelp": showhelp
    };
    var URL = Get_ESURL(false, true, false, "users", username)
    return Do_Axios(axios, 'post', URL, adduser, null, false);
}

function Get_UserFromES(axios, username) {
    var URL = Get_ESURL(false, true, false, "users", username)
    return Do_Axios(axios, 'get', URL, null, null, false);
}

function Get_PostQueryToES(axios, query, index) {
    var URL = Get_ESURL(true, false, false, index)
    return Do_Axios(axios, 'post', URL, query, null, false);
}
Related