Server sent event CORS issue with simple traefik configuration

Hi,
I'm facing a CORS issue with SSE and I don't know what to do.

Context:

  • NestJS ^7.6
  • Angular ^12 with EventSourcePolyfill (for the authorization header)
  • Docker/Docker Compose and traefik 2 (neither compress nor any special options enabled, I just use traefik as reverse proxy and https feature (only on production))

Problem:
Without docker and traefik, everything works fine.
But when I use these tools, the SSE stops working with a CORS issue (any other classic request works well).
I don't know if I missed something...

My docker compose file (I remove the unnecessary lines) looks like this:

version: "3.9"

services:
  frontend:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`frontend.project.localhost`)"
    depends_on:
      - api

  api:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.project.localhost`)"

  traefik:
    image: traefik:v2.4
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
    ports:
      - "80:80"
      - "8090:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Best regards

Hello @lheido,

When you say you get a CORS issue....what issue are you encountering?

Are you getting an error? Failed requests? What issue are you experiencing?

Hello @daniel.tomcej,

Thank you for your answer.
The error just says:
Access to fetch at 'http://api.project.localhost/api/resources/dump' from origin 'http://frontend.project.localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Hello @lheido,

It appears that you have one application api.project.localhost trying to load content from another domain frontend.project.localhost. This is exactly what CORS is designed to prevent.

There are many excellent resources online that explain how CORS works such as (What is CORS? Complete Tutorial on Cross-Origin Resource Sharing), so I won't duplicate that here.

Simply, if you want to allow one application to access another via the client, you need to add CORS headers to allow this to happen. You will most likely want to use the headers middleware to add these: (Headers - Traefik)

The problem is that other the classic HTTP requests (with the same cross origin behavior) works well.
Only the SSE requests failed.
The strange thing here is when I'm running my app without traefik (localhost:3000 and localhost:4300), the SSE requests works too.
Sorry if I'm not explaining myself properly (It's a difficult issue to explain for a non native speaker)

In that case, you are not using a different domain. They are both using localhost.

:thinking: Ok, I was almost sure the port was taken into account in the Same Origin Policy.
What about my other classic HTTP requests (using same cross origin behavior) why are they working ?
I don't understand what escapes me.

You are correct, there is overlap between SOP and CORS, and you are correct that the port is taken into account when determining the origin.

Note that CORS don't apply to "simple requests": (Cross-Origin Resource Sharing (CORS) - HTTP | MDN) So it is possible that some requests may succeed due to being simple, but others will fail due to not being simple.

Ok thank you, I haven't heard about that ! It's seems to be an OPTIONS request related issue.
I'm going to investigate !
Thank you for your time

1 Like

In the end, the issue was not related to CORS, it was in fact a wrong http header ("Transfert-Encoding" = "identity") solved by upgrading NestJS to 8.0.4

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.