Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IE9 - No Living Connections #96

Closed
incorvia opened this issue May 1, 2014 · 31 comments
Closed

IE9 - No Living Connections #96

incorvia opened this issue May 1, 2014 · 31 comments

Comments

@incorvia
Copy link

incorvia commented May 1, 2014

I'm using the angular.js module integration for the ElasticSearch library in my companies website. The application works fine on > IE10 but when I load the application in IE9, I get the dreaded 'No Living Connections' error.

In the documentation for ElasticSearch it states: "We also test in IE 9, but there is a known issue with making non-standard (get/post) requests across domains.". This may be due to the fact that 'standard' requests are the only requests allowed by XDomainRequest which, I believe IE9 uses for cross domain requests:

http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

There was some thought that in order to establish the connection or keep it alive, a 'HEAD' request would need to be made and not being able to make a XDomainRequest via HEAD could be the issue. The thought was that perhaps forcing the client.search method to use a 'GET' request by setting the 'method' parameter would in fact fix it.

In testing it seems that instantiating a new client and making the most generic match_all query with a 'GET' request fails

$: client = elasticsearch.Client({ host: ELASTICSEARCH_URL})
=> EsApiClient {close: function, transport: Transport, cluster: ClusterNS, indices: IndicesNS, _namespaces: Array[2]…}
$: client.search({method: 'GET', body: JSON.stringify({query: {match_all: {}}})})
=> undefined
=> Uncaught TypeError: Cannot read property 'reject' of undefined elasticsearch.js?body=1:27265

Note that using a 'POST' will correctly return a promise and I've redacted my elasticsearch_url but did use an appropriate one. I know that there is a limitation in Javascript that prevents adding data to the body of a 'GET' request and depending on how this library internally handles the 'body' parameter this may be an issue it is running up against.

In short, if we were able to use a 'GET' request (which I'm not convinced we are able to) I'm not sure that that will fix the initial issue of 'No Living Connections'. I know that it is stated that IE9 is supported but I do not see how it can be given the limitations I am facing. If it is not capable of being supported, then I would suggest it should be mentioned in the docs.

Any help is appreciated!

@incorvia
Copy link
Author

incorvia commented May 5, 2014

@spenceralger were you able to replicate this error using IE9? Just curious.

@spalger
Copy link
Contributor

spalger commented May 5, 2014

I ran into several roadblocks getting IE9 running on my mac, but it's on my TODO list for today. Sorry about that!

@incorvia
Copy link
Author

incorvia commented May 5, 2014

@spenceralger no need to be sorry, thanks for looking into that.

@spalger
Copy link
Contributor

spalger commented May 5, 2014

Alright, I have IE9 up and running and I'm not getting any errors using HEAD and POST requests... unexpected.

To your previous point, the client will use POST by default (for methods like search) and only GET when told to explicitly.

While these tests are far from complete, we need to find a way to replicate this predictably before I can help much more.

ie9_-win7__running__and_ie9-_no_living_connections__issue__96__elasticsearch_elasticsearch-js

@incorvia
Copy link
Author

incorvia commented May 6, 2014

Thank you so much, will look into this more today and see if I can come up with a reproducible use case.

@incorvia
Copy link
Author

incorvia commented May 6, 2014

I'm attempting to setup a common setup so we can verify this. This is the closest I've gotten so far:

http://jsfiddle.net/stnxx/

While it does not produce the no living connections error, it does succeed on IE10 but fail in IE9... after 30 seconds it eventually returns:

{"message":"Request Timeout after 30000ms","stack":"","isAsync":true}

Note that you will need to place a valid ElasticSearch URL where appropriate.

@spalger
Copy link
Contributor

spalger commented May 6, 2014

Alright, that did it.

You are right, IE9 is not properly supported. I will work on support and tests to verify the support claims. It seems that IE treats localhost special, and puts it within an "intranet zone" or something, so it can access anything else on localhost, but only things on localhost can access localhost....... it's all horrible and annoying but I'll get it working (or pull in a module to got it working).

@spalger
Copy link
Contributor

spalger commented May 7, 2014

Since I couldn't find a simple list detailing the faults that Microsoft's XDomainRequest object has, I'm going to document them here for now:

  1. only GET and POST are supported
  2. Authentication can't be used
  3. Custom headers can't be set
  4. Requests can't be made to localhost unless the page is running on localhost
  5. Protocols of the parent window and the request must match.
  6. Status codes are not available for the responses
  7. error-type response codes (not sure what range this includes) trigger an error

Because several of these will cause things to break only in IE9/8 I have decided to make them opt-in with an ie9 config parameter. Set it to true and elasticsearch.js will attempt to make requests for you assuming that your requests conform to the above.

@spalger
Copy link
Contributor

spalger commented May 8, 2014

@incorvia Can you check out http://jsfiddle.net/75QSs/1/

@JohnTimothyDaly
Copy link

You are linking to esjs.localhost/dist/elasticsearch.js, there is no elasticsearch defined

@spalger
Copy link
Contributor

spalger commented May 8, 2014

Oops, sorry. Updated the link to http://jsfiddle.net/75QSs/1/

@incorvia
Copy link
Author

incorvia commented May 8, 2014

@spenceralger, looks like that did the trick! Hope it wasn't too much of a pain.

@spalger
Copy link
Contributor

spalger commented May 8, 2014

@incorvia thanks for looking it over. Glad it worked! I'll work on some tests to verify that it continues to work and will get it merged soon.

@incorvia
Copy link
Author

incorvia commented May 8, 2014

@spenceralger if I turn on the IE9 flag with your modified library, might other features within the library act differently/break? I'm assuming something would.. otherwise you wouldn't have a flag you would just make IE9 compatible.

@spalger
Copy link
Contributor

spalger commented May 8, 2014

Correct, see the list in this comment.

As for right now, those features will work in every browser except IE9. I might try enforcing the limits across the board when the ie9 flag is set... Need to think about that.

@JohnTimothyDaly
Copy link

I've tried it with IE8 (including an es5 shim) and it works there too

@spalger
Copy link
Contributor

spalger commented May 8, 2014

@JohnTimothyDaly Good to know!

@spalger
Copy link
Contributor

spalger commented May 8, 2014

I discussed the posibility of adding the ie9 config param with my colleagues, and we all agree that in it's _current_ state it is not something we want to ship/be responsible for. We are discussing our other options, but unless demand for IE9 support is stronger we might drop it completely.

For the time being, I will remove the accidentally-illegitimate claim of IE9 support from the readme.

Now, if you guys really want to allow users to use IE9 you can use the setup in this fiddle. It uses a custom connectionClass defined in this gist.

The connection class forces requests in all browsers to conform to the same limitations imposed by IE (AFAIK) and really is only good for pulling info out of elasticsearch. I'm sorry that we don't have any better options for you at this time.

@incorvia
Copy link
Author

incorvia commented May 9, 2014

@spenceralger I understand not wanting to go through the effort of providing official support on IE9 but greatly appreciate you providing this gist for some backwards compatibility. I'll give it a go today.

@spalger spalger closed this as completed May 19, 2014
@joshijimit
Copy link

@spenceralger or @incorvia

Sorry to post on closed issue, I am looking for the solution to make your elastic client for angular (http://www.elasticsearch.org/guide/en/elasticsearch/client/javascript-api/current/browser-builds.html) to work with OLD IE browser like 8 and 9.

After reading this discussion I got that we can make it work using the gist provided by spenceralger. However, I am struggling how to configure it with angular client..

I believe, I can use this gist with angular client too. Can someone please help me to set this gist with angular client too.

@spalger
Copy link
Contributor

spalger commented May 29, 2014

@joshijimit I feel like you have two options:

1. Use a proxy

If you are writing an application with any type of server component, I recommend writing a simple proxy that will allow you to send requests directly to elasticsearch using the same host as the rest of the application. This way, you will not be limited by the cross domain implementation in older versions of IE and can use the angular build of the client.

You can tell the client to send all requests to a specific path, making your config look something like this:

module.service('es', function (esFactory, $location) {
  return new esFactory({
    host: {
      protocol: $location.protocol(),
      host: $location.host(),
      port: $location.port(),
      path: '/proxy-to-es'
    },
    // other config...
  });
});

2. Don't use the angular build

The angular build is basically just three optimizations on top of the generic client: it uses the $http service for ajax, the $q service for promises, and registers a Factory. If you use the standard build you can still configure the client use $q promises, then everything should work smoothly if you stay away from callbacks and use the compatibility connector from the gist. Recreate the esFactory like so:

// ensure that the elasticsearch and Ie9CompatibleXhrConnector files are loaded
module.factory('esFactory', function ($q) {
  return function Factory() {
    return new elasticsearch.Client({
      host: 'http://otherdomain.com:9200',
      connectorClass: Ie9CompatibleXhrConnector,
      defer: function () {
        return $q.defer();
      }
    });
  };
});

@joshijimit
Copy link

Thank You @spenceralger. I will give it a try and get back with the result.

@joshijimit
Copy link

@spenceralger , I am facing trouble loading elasticsearch and Ie9CompatibleXhrConnector in my angular module.I have checked some articles and blogs on how to load external JS in angular but couldn't get any luck. Can you please help on how I can load these two files to use your option 2 code in my angular module.

I am looking to load those JS something like below

var elasticsearch = /*Some way to load elasticsearch.js*/;
var Ie9CompatibleXhrConnector = /*Some way to load Ie9CompatibleXhrConnector.js*/;
 
angular.module( 'mymodule', [
  'ui.router'  
])
.factory('esFactory', function ($q) {
  return function Factory() {
    return new elasticsearch.Client({
      host: 'http://hostname:9200',
      connectorClass: Ie9CompatibleXhrConnector,
      defer: function () {
        return $q.defer();
      }
    });
  };
})
.service('es', ['esFactory', function(esFactory) {
        return esFactory({});
}])

@spalger
Copy link
Contributor

spalger commented May 30, 2014

Sorry if I mislead you a bit there, I just mean to ensure that their script tags come first. Something like this:

<script type="text/javascript" src="elasticsearch.js"></script>
<script type="text/javascript" src="elasticsearch.ie9Connector.js"></script>
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="myModule.js"></script>

@joshijimit
Copy link

@spenceralger

You haven't mislead me so don't be sorry. In fact you helped me a lot here. :)
Thanks to you it is working fine now in IE 9. However, in IE-8 it is throwing below js error even with es5 shim.

Message: Object doesn't support this property or method
Line: 55
Char: 3
Code: 0
URI: http://localhost:7070/BrakesAngular/vendor/elastic-search/Ie9CompatibleXhrConnector.js

I have used your initial version of elasticsearch.js from http://jsfiddle.net/75QSs/1/ and it worked in IE-8 as well with es5 shim. So can you help me to figure out the patch for above JS issue with Ie9CompatibleXhrConnector js so we can use it as a standard solution for IE-8 as well as 9.

Thanks in advance.

@spalger
Copy link
Contributor

spalger commented Jun 3, 2014

Interesting, looks like that line is calling Object.create which es5-shim claims to mostly support.

@spalger
Copy link
Contributor

spalger commented Jun 5, 2014

@joshijimit did you figure out how to get this working in IE8?

@joshijimit
Copy link

Nope, I have spent few hours but no luck. So decided to go with your old js which is working fine in ie 8. Will probably check on it in near future once I will get time from other priorities.

Would be great if you can also check it once from your end too.

@obashmat
Copy link

Hi guys,
Does anyone have any update on this topic?
@spalger currently this gist with the compatibility connector does not exist. Can i find this connector somewhere else?

Thank you for any update.

@nicoletaCh
Copy link

Hi guys,

I am also interested in finding the compatibility connector. Could anyone help?

Thanks!!

@timraymond
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants