'Weird Apache2 Socket.io Javascript CORS Error

I am working on a chat app, and have encountered this weird issue with CORS (cross origin resource sharing). I keep seeing the error Access to XMLHttpRequest at 'https://wyvern-api.tkdkid1000.net/socket.io/?EIO=4&transport=polling&t=O2mhMJM&sid=yo6T124_I6kZbpv1AAAg' from origin 'https://wyvern.tkdkid1000.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. in the chrome console. I have the npm cors module added on my express server, and I setup cors in the socket.io server. Both my express and socket.io server code are below (modified to only show relevant stuff, tell me if you need the whole thing):

import cors from "cors"
import express from "express"
import fs from "fs"
import { createServer } from "http"
import path from "path"
import { initSockets } from "./sockets"

const app = express()
const server = createServer(app)

app.use(express.json())
app.use(
    cors({
        origin: "*",
        methods: ["GET", "POST", "PUT", "DELETE"]
    })
)

const io = initSockets(server)

export { server, io }

function initSockets(server: http.Server) {
    const io = new Server(server, {
        cors: {
            origin: "*",
            methods: ["GET", "POST", "PUT", "DELETE"]
        }
    })
...
}

also, my apache2 server site conf file

<VirtualHost *:443>
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    ServerName wyvern-api.tkdkid1000.net

    ProxyPass /socket.io/ws/ ws://localhost:3000/socket.io/
    ProxyPassReverse /socket.io/ws/ ws://localhost:3000/socket.io/

    ProxyPass /socket.io/ http://localhost:3000/socket.io/
    ProxyPassReverse /socket.io/ http://localhost:3000/socket.io/

    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) "ws://localhost:3000/$1" [P,L]

    ProxyTimeout 3
    Header set Access-Control-Allow-Origin "*"

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/tkdkid1000.net/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/tkdkid1000.net/privkey.pem
</VirtualHost>

Followed some other stackoverflow guides to get the second and third proxies (and the timeout) and the rewrite thing. I doubt this is the issue, but it might be so I included it.

Now if it's a client issue (which I highly doubt), I am gonna include how I initialize the socket. It's an entire file in case it's some production error or something.

import axios from "axios"
import dayjs from "dayjs"
import isToday from "dayjs/plugin/isToday"
import isYesterday from "dayjs/plugin/isYesterday"
import { createElement } from "react"
import { createRoot } from "react-dom/client"
import { io } from "socket.io-client"
import { App } from "./App"
import "./scss/main.scss"

export function Production() {
    const serverUrl = "https://wyvern-api.tkdkid1000.net"
    console.log("Loading production server at " + serverUrl)

    axios.defaults.validateStatus = (status) => status >= 200 && status < 500
    axios.defaults.baseURL = serverUrl

    const socket = io(serverUrl)

    dayjs.extend(isYesterday)
    dayjs.extend(isToday)

    createRoot(document.getElementById("app")).render(
        createElement(App, {
            socket: socket
        })
    )
}

And the apache2 config file:

<VirtualHost *:443>
    ServerName wyvern.tkdkid1000.net
    
    DocumentRoot "/var/www/wyvernchat"
    DirectoryIndex index.html
 
    <Directory "/var/www/wyvernchat">
        AllowOverride All
        order allow,deny
        allow from all
        Header set Access-Control-Allow-Origin "*"

        RewriteEngine on

        RewriteCond %{REQUEST_FILENAME} -s [OR]
        RewriteCond %{REQUEST_FILENAME} -l [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^.*$ - [NC,L]
        RewriteRule ^(.*) /index.html [NC,L]
    </Directory>

    Header set Access-Control-Allow-Origin "*"

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/tkdkid1000.net/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/tkdkid1000.net/privkey.pem
</VirtualHost>

To reproduce (not an ad or anything, just need to use the actual server for demonstration): Go to https://wyvern.tkdkid1000.net Register and login Create a guild with the plus icon on the left Try sending messages or loading messages Open console and see errors

If there is some simple solution, I apologize in advance. This is my first time ever deploying an app with different client and server domains. I fixed the CORS issue with my original app (basic http requests loading and stuff), just never really dealt with this and websockets before.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source