ryo
ryo

Reputation: 2167

How to check whether server supports HTTP/2 in JavaScript on browser

I'd like to know the way to check whether a server supports HTTP/2 in JavaScript in Browser. If possible, I would like to know the way without using an API server.

The reason to check is as follows.

Upvotes: 2

Views: 2314

Answers (4)

divillysausages
divillysausages

Reputation: 8053

For the most part, this will be invisible for you. If the server support HTTP/2 and you're using a modern browser, it'll happen automatically, provided your website is delivered over HTTPS

That means that local testing, unless you're serving your own certificate, will always be HTTP/1

If you've access to the server, once way of finding out is by looking at request headers. From https://developers.google.com/web/fundamentals/performance/http2#binary_framing_layer:

Unlike the newline delimited plaintext HTTP/1.x protocol, all HTTP/2 communication is split into smaller messages and frames, each of which is encoded in binary format.

So basicially, if your headers are in binary, your running HTTP/2.

@Rojo's answer also works for me, running it in the web console on this page, (but again, not locally because of the HTTP requirement)

Upvotes: 0

Rojo
Rojo

Reputation: 2869

This question is a duplicate, so here is the most upvoted answer from Punit S:


Navigation Timing 2 API provides this information:

performance.getEntriesByType('navigation')[0].nextHopProtocol

The above should return 'h2' on a page that got fetched using HTTP 2

A note on limited compatibility of nextHopProtocol:

Navigation Timing Level 2 API is currently in working draft status so support for the nextHopProtocol (which is being introduced with Level 2 API) will be limited (unsure of exact browsers supporting it since caniuse currently doesn't include Navigation Timing Level 2 API).


(end quote)

I tested the above code on my localhost site served by Apache 2.2 and received "http/1.1" (I'm not exactly sure how to change the type of HTTP). On other sites, all of them have outputted "h2" (I only tested a few).

Upvotes: 1

pguardiario
pguardiario

Reputation: 55012

The only way I've found is try to connect and catch the error if it fails:

const http2 = require('http2')

; (async() => {
  let host = 'https://www.amazon.com'
  const http2Support = await new Promise((resolve, reject) => {
    const client = http2.connect(host)
    client.on('error', (err) => {
      resolve(false)
    })
    client.on('remoteSettings', (settings) => {
      resolve(settings)
    })
  })
  console.log(http2Support)
}

Upvotes: 0

Barry Pollard
Barry Pollard

Reputation: 46110

This is tricky for a few reasons.

Even if a server supports HTTP/2, a client may not use it. For example if a proxy (often used in corporate environments or by anti-virus products) may not support HTTP/2 abs so force use of HTTP/1.1 despite the fact the client and server both support HTTP/2.

The upcoming Resource Timing Level 2 specification proposes a nextHopProtocol attribute that would give this and support is reasonably good, though it’s notable that Safari doesn’t support this so given the prevalence of iOS that’s probably a sizeable chunk of your web visitors. Plus it’s not approved yet so may change.

You could also detect this server side as many web servers expose the connection information in variables. This could be used to set an HTTP Header or a response in the Body to inform the client of the support.

However even if you could accurately measure this, it may not be as accurate an indication as you think of the number of concurrent requests that will be used. Google Chrome for example is experimenting with throttling the number of concurrent requests on slow connections. This can be seen from Chrome 74 when using the “Slow 3G” network profile in Developer Tools.

Upvotes: 1

Related Questions