0

I'm having a problem with successfully using the application/json answer retrieved from an ElasticSearch server with jQuery. Firefox tells me that I'm getting a valid 200 OK answer to the HTTP GET and the Firefox Network Monitor can correctly parse the JSON. jQuery however does not call the success / done callback, only fail and always are called.

ElasticSearch is telling me with a Warning header:

299 Elasticsearch-5.4.1-Unknown "Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header." "Mon, 03 Jul 2017 07:59:32 GMT"

As soon as I add a

contentType:"application/json; charset=utf-8",

to the $.ajax() function, Elasticsearch only returns an empty result.

The JS code for the "valid" but not callback-calling version:

  var postData = {
      "_source": ['title', 'url'],
      "query" : {
          "match": {
              "body": "lorem"
          }
      },
      "highlight" : {
          "pre_tags" : ["<b>"],
          "post_tags" : ["</b>"],
          "fields" : {
              "body" : {
                  "fragment_size" : 150,
                  "number_of_fragments" : 1,
                  "no_match_size": 150
               }
          }
      }
    };
  function docsearch(){
    var data = JSON.stringify(postData);
    $.ajax({
      //contentType:"application/json; charset=utf-8",
      url: "http://127.0.0.1:9200/myindex/_search?pretty=true",
      type: "POST",
      dataType: "json",
      data: data,
      success: function (data) { console.log(data); }
    }).done(function() {
      alert( "success" );
    })
    .fail(function(data) {
      console.log( data );
    })
    .always(function() {
      alert( "complete" );
    });
  };

The GET headers:

Host: 127.0.0.1:9200
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost/
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 208
Origin: http://localhost
DNT: 1
Connection: keep-alive

And result headers:

Content-Encoding: gzip
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Warning: 299 Elasticsearch-5.4.1-Unknown "Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header." "Mon, 03 Jul 2017 07:59:32 GMT"

And the result JSON:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.25124598,
    "hits" : [
      {
        "_index" : "myindex",
        "_type" : "post",
        "_id" : "10",
        "_score" : 0.25124598,
        "_source" : {
          "title" : "Lorem ipsum"
        },
        "highlight" : {
          "body" : [
            "<b>Lorem</b> ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat"
          ]
        }
      }
    ]
  }
}

The output of the fail callback:

09:59:32.973 Object { readyState: 0, getResponseHeader: .ajax/y.getResponseHeader(), getAllResponseHeaders: .ajax/y.getAllResponseHeaders(), setRequestHeader: .ajax/y.setRequestHeader(), overrideMimeType: .ajax/y.overrideMimeType(), statusCode: .ajax/y.statusCode(), abort: .ajax/y.abort(), state: .Deferred/e.state(), always: .Deferred/e.always(), catch: .Deferred/e.catch(), 9 more… }

Can anyone provide some insight, why jQuery is not calling the success function? I found that it may be related to Transfer-Encoding: chunked.

Thanks

Sven
  • 19
  • 4
  • Why you are sending "var data = JSON.stringify(postData);" in string format??? Rather send the Object in the form of data: postData. – Shiladitya Jul 03 '17 at 08:28
  • Then ElasticSearch returns an error 406: "Content-Type header [application/x-www-form-urlencoded; charset=UTF-8] is not supported". And with contentType:"application/json; charset=utf-8" ES returns an empty result. – Sven Jul 03 '17 at 08:48
  • Still I believe the problem lies with constructing the postData. Please check the log in ElasticSearch which will give you the exact query that you fired from UI. Along with that please add Content-Type: application/json; – Shiladitya Jul 03 '17 at 09:09
  • Got some reference for you https://stackoverflow.com/questions/44283921/what-does-a-406-not-acceptable-error-code-from-elasticsearch-mean – Shiladitya Jul 03 '17 at 09:10
  • I probably found the problem. It has nothing to do with JS and is not properly reflected in the example I've shown. It's about a missing Access-Control-Allow-Origin header, because the elasticsearch server is actually residing on a different host. And I did not enable all debug output on Firefox. Chromium did show me the helping error message. – Sven Jul 03 '17 at 09:14

1 Answers1

0

Sorry for bothering. The answer really was a missing Access-Control-Allow-Origin header. And because it's a POST, it also needs to be allowed:

Header set Access-Control-Allow-Origin "http://elasticsearch-host.domain"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Sven
  • 19
  • 4