Internet Explorer’s problems with asynchronous calls and their fixes

Today I stumbled again – as every single developer eventually will – with Internet Explorer’s brilliant and different way of handling things.

I implemented a socket listener thread to a port on the server side and a simple HTTP GET request from the client side. The main objective here was to make the server do a simple task based on the parameters sent from a client.

Here’s the server-side Java code. This is the working bug-free final version, just to save space.

new Thread(() -> {
    try {
        ServerSocket listener = new ServerSocket(9999);
        try {
            while (true) {
                Socket socket = listener.accept();
                socket.setKeepAlive(false);
                try {
                    boolean ok = false;
                    String inputLine;
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                    while (StringUtil.isNotEmpty(inputLine = in.readLine())) {
                        if (inputLine.startsWith("GET") && !inputLine.contains("favicon")) {
                            Map<String, String> params = new HashMap<>();
                            for (String param : inputLine.replace("GET /?", "").replace(" HTTP/1.1", "").split("&")) {
                                String[] kvPair = param.split("=");
                                params.put(kvPair[0], kvPair[1]);
                            }
 
                            if (params.containsKey("target")) {
                                switch (params.get("target")) {
                                    case "key":
                                        // do stuff
                                        ok = true;
                                        break;
                                     default:
                                        break;
                                }
                            }
                        } else if (inputLine.startsWith("OPTIONS")) {
                            ok = true;
                        }
                    }
                    if (ok) {
                        out.println("HTTP/1.1 200 OK");
                    } else {
                        out.println("HTTP/1.1 400 Bad Request");
                    }
                    out.println("Access-Control-Allow-Origin: *");
                    out.println("Access-Control-Allow-Headers: accept, headers");
                    out.println("Access-Control-Allow-Methods: GET");
                    out.println("Cache-Control: no-cache,no-store");
                    out.println("Connection: Close");
                    out.println("Keep-Alive: timeout=1");
                    out.close();
                    in.close();
                } catch (Exception ex1) {
                    ex1.printStackTrace();
                } finally {
                    socket.close();
                }
           }
         } catch (Exception ex2) {
             ex2.printStackTrace();
         } finally {
            listener.close();
         }
    } catch (Exception ex3) {
    }
}).start();

Problem 1: Caching

Symptoms:

  • Your first asynchronous call works perfectly
  • Every other call seems to work on the front, but the server side doesn’t see a sign of them

Internet Explorer likes to do a lot of caching. Turns out that it also caches asynchronous calls and their responses. This really doesn’t work here, because I need the server to do something on every call and I do nothing with the return data.

To get around this problem, I had to add another header to the response.

out.println("Cache-Control: no-cache,no-store");

This tells the browser not to cache the response it’s receiving.

Problem 2: Keep-Alive

Symptoms:

  • Client sends requests, but occasionally they hang on the server
  • Sending a request from Internet Explorer delays a simultaneous request from Chrome

This was a bit harder to figure out. Internet Explorer’s built-in keep-alive time is 60 seconds. This messes up the requests made by IE itself and keeps the socket occupied and inactive also for other browsers.

To fix the problem where IE caused the problems to itself, I needed to add these rows to the code above.

out.println("Connection: Close");
socket.setKeepAlive(false);

The first one tells the requesting browser that it should close the connection after getting a response. The second one disabled the server’s own keep-alive.

However, this didn’t fix the problem where IE kept the server occupied after a request where other browsers didn’t.

out.println("Keep-Alive: timeout=1");

The last fix here tells the browser that the keep-alive timeout of the server is very low. This finally made Internet Explorer conclude that I really wanted it to close the connection after a response.

The asynchronous call was called from an Angular application’s $http -call to a Java 8 based server. The client here was IE version 11.

 

Miro Metsänheimo

A software developer from Finland born in -92. I'm passionate about computers and technology. Feel free to message me about anything!

 

Leave a Reply

Share On Facebook
Share On Twitter
Share On Google Plus
Share On Linkdin