Search code examples
javascriptgoogle-chrome-extensionserver-sent-events

What causes EventSource to trigger an error in my Chrome extension?


I have the following code in a background_script in a Google Chrome extension:

var source = new EventSource("http://www.janywer.freetzi.com/events/groupshout.php");
source.addEventListener('message', function (e) {
    console.log('message', e.data);
}, false);
source.addEventListener('open', function (e) {
    console.log('open');
}, false);
source.addEventListener('error', function (e) {
    console.log('error')
}, false);

My problem is the following: Whenever I load the extension, it's saying 'error', but how do I find out what exactly triggered the error?


Solution

  • The specification defines only a few possible cases for the "error" event to be triggered, which are:

    • A cross-origin request was initiated, but the expected CORS headers were not received. This includes:
      • Access-Control-Allow-Origin is not set or does not match the origin URL.
      • You've set withCredentials:true (via the second parameter of EventSource), but the server did not reply with Access-Control-Allow-Credentials: true.
    • A network error has occurred.
    • The http status is not 200, 305, 401, 407, 301, 302, 303 or 307.
    • The user agent (browser) is trying to re-establish a connection.
    • The http status is 200, but the Content-Type header of the response is not `text/event-stream.
    • A redirect occurred, which resulted in one one the previous conditions.

    When a CORS error occurs, Chrome will usually log the following message to the console:

    EventSource cannot load http://example.com/eventsource. Origin http://origin.example.com is not allowed by Access-Control-Allow-Origin.

    For some reason, Chrome does not show this error when a redirect has taken place.


    You have probably added the "http://www.janywer.freetzi.com/*" permission to your manifest file, causing the initial request to pass. This page redirects to a different domain (without www-prefix). You have probably not added this domain to your manifest file, so Chrome attempts a CORS-enabled request. The expected headers are not received, so Chrome aborts the request.

    This can be solved in two ways:

    • Add all involved domains to your file, e.g.

      "permissions": [
          "http://www.janywer.freetzi.com/*",
          "http://janywer.freetzi.com/*"
      ]
      

      (see match patterns in the Chrome extension documentation)

    • or let the server reply with the expected CORS headers. In PHP:

      header("Access-Control-Allow-Origin: *");
      

      This allows any page to access your URL. To restrict access to your extension only, use:

      header("Access-Control-Allow-Origin: chrome-extension://EXTENSION ID HERE");