Search code examples
google-chromehttpprotocolseventsource

EventSource Modifying Protocol


I work in a corporate environment and found an issue I can't resolve.

It has to do with EventSource changing the URL param from HTTP to HTTPS.

const url = 'http://localhost:8080'; // <-- using HTTP not HTTPS
new window.EventSource(url);

Which results in the browser throwing this error:

GET https://localhost:8080 net::ERR_TUNNEL_CONNECTION_FAILED

I am developing on a website using HTTPS so maybe this is by design that it uses the same protocol. Anyone experienced this issue or know how to resolve it?

--- Update ---

Looks like it is by design. When attempting this on another HTTPS site I got this:

Mixed Content: The page at 'https://...' was loaded over HTTPS, but requested an insecure EventSource endpoint 'http://localhost...'. This request has been blocked; the content must be served over HTTPS.

The question still remains, how do I get around this?


Solution

  • Eventsource won't change between http and https. Are you using the HTTPS Everywhere plugin for Chrome, or something like that?

    I think you are being hit by the same-origin policy. What this means is that the SSE connection must be to the same origin, which basically means the same hostname and domain, same scheme (i.e. either both http or both https) and same port.

    You can use CORS to get around this. At the top of your SSE script you need to send back this header:

    Access-Control-Allow-Origin: *
    

    This says anyone, from anywhere, is allowed to connect and get the data stream. It has to be done on the server script, there is no way to do it from the client. (By design: the whole point of same-origin policy is to stop people using other people's content and making it look like their own, without permission.)

    Shameless Plug: see my chapter 9 in my book (Data Push Apps with HTML5 SSE, O'Reilly) for finer control of allow-origin, and how it interacts with cookies and basic auth.

    BTW, I notice I mention that Chrome won't work with self-signed https certificates. To be honest I'm not sure if that is still the case, but that might also be something to watch out for when using https and localhost.