The Socket.io and express app are facing connectivity issues as a result of a CORS error stating: "It is not allowed to use the wildcard '*' in the 'Access-Control-Allow-Origin' header"

I'm going crazy over a trivial issue I've encountered.

My socket.io/express app is deployed on Digital Ocean using Docker setup.

To enable https, I'm utilizing Caddy within my Docker setup for automatic https.

I've been attempting to connect to this setup through my domain and from my local React app residing on localhost:3000. However, I keep encountering the following error:

The CORS policy is blocking access to the XMLHttpRequest at '' from origin 'http://localhost:3000'. This occurs because the 'Access-Control-Allow-Origin' header value in the response cannot be '*' when the request's credentials mode is 'include'. The withCredentials attribute controls the credentials mode of requests initiated by the XMLHttpRequest.

I've explored numerous solutions on SO, but none seem to resolve the issue.

  • I've tweaked the options of the cors middleware
  • I've added custom middleware with specific headers
  • I've attempted using localhost:3000 as the origin
  • ...

Unfortunately, nothing seems to work. I'm at a loss for what else I can do to rectify this problem.

Any guidance would be greatly appreciated.

Here's how my docker-compose file appears:

version: '3.6'
services:
  media-server:
    build:
      dockerfile: Dockerfile
      context: ./
    ports:
    - "8080:5000"
    expose: 
      - "5000"
  caddy:
    image: abiosoft/caddy:0.11.0
    depends_on:
      - "media-server"
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /root/Caddyfile:/etc/Caddyfile
      - /root/.caddy:/root/.caddy

My Caddyfile configuration is detailed below:

https://mediaserver.domain.dev {
  proxy / http://media-server:8080 {
    websocket
    transparent
  }
  cors
}

And here's how my server setup code looks like:

import cors from 'cors';
import express from 'express';
import socket from 'socket.io';

import { intialiseWebSocketConnection } from './socketio';

const app = express();

app.use(cors());

const server = app.listen(5000, function () {
  console.log('Server is connectedd on *:5000');
});

const io = socket.listen(server);

intialiseWebSocketConnection(io);

Answer №1

When making a cross-origin request with the credentials flag set and the Access-Control-Allow-Origin set to (*), for security reasons, it is not allowed. To solve this issue, there are two approaches. If you do not need to send credentials, ensure that the credentials flag is false. For example, if you are using an XMLHttpRequest, make sure that withCredentials is set to false (which is the default). If you are utilizing the Fetch API, ensure that Request.credentials is set to "omit".

If sending credentials is necessary, you must specify the Access-Control-Allow-Origin in your server's response to match the origin from which the requests are being sent, rather than allowing any origin (*). To determine what your origin is, inspect the value of the Origin header in the requests you send to the server.

By default, cors() sets the Access-Control-Allow-Origin to *. Consider updating it to:

cors({
    origin: "http://localhost:3000",
    credentials: true
});

Note that Chrome does not support localhost as an origin. To work around this limitation during development, you can launch Chrome with the --disable-web-security flag.

Answer №2

If you want to avoid CORS errors when using socket.io connections, there’s a handy trick you can use. By default, socket.io initiates each connection with some regular HTTP calls. If everything goes smoothly, it then switches to a webSocket transport (and proceeds to run socket.io over this webSocket transport). However, these initial HTTP calls are bound by CORS restrictions.

But, if you instruct socket.io to start off directly with the webSocket transport, you won’t have to worry about CORS restrictions at all. You can achieve this on the client side by adding this line of code:

const socket = io({transports: ['websocket']});

Even though a webSocket connection always begins with an HTTP request, that specific HTTP request (with the correct upgrade header set) is not impacted by CORS restrictions.

The only drawback I know of with this approach is that your code will not function in browsers that don’t support webSockets. This would typically be a very outdated browser. Most modern browsers, including IE10 released in 2012, have been supporting webSockets since around 2013. It's somewhat puzzling why socket.io still has HTTP polling as the default method, given its network inefficiency for every new connection. Regardless, you can easily bypass this with io({transports: ['websocket']});.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Javascript Date and Time Validation

My application includes code that is supposed to display HTML pages based on today's date and the time of day (morning, afternoon, or evening). However, it seems like there is an issue with how the time is being checked. Currently, at 2:53pm, only the ...

Updates to class variable values in jQuery are failing to take effect

Attempting to create my first JavaScript class has presented some challenges, specifically when it comes to updating a class variable. Despite hours of testing different approaches, I still can't seem to get it right! function ClassName(productId) { ...

Enhance your API Restful resource by incorporating subcategories into the filtering options

Let me clarify with an example since the title may be unclear. Here's how we can construct a resource path for such a scenario: GET /courses/?language=english&active=true/units I am looking to filter courses without using an id and then retriev ...

Getting started with `sessionStorage` in a React application

Currently, I am attempting to save an item in sessionStorage prior to rendering. The code snippet I have looks like this: componentWillMount() { sessionStorage.setItem("isUserLogged", false); } However, I encountered an error stating th ...

What could be causing the console to display undefined?

Can anyone help me with an issue I'm having while making an AJAX call using fetch and promises? I have successfully displayed the temperatures, but for some reason, the location is showing up as undefined. Here is the code snippet: function getWeat ...

The onKeyUp event is not functioning as expected in React, unlike the onChange event

For a React coding challenge, I am required to update a value onKeyUp instead of onChange. However, after changing it to onKeyUp, my fields are not updating and I cannot type anything into the textarea. class MarkdownApp extends React.Component { constr ...

Ways to showcase the resulting answer using vue.js?

My current query is regarding the display of error messages. How can I show the error message "passwords do not match" {"errors": {"password": ["Passwords donot match"]}, "status": false, "msg": "Validation erro", "error-type": 0} In my code snippet, I h ...

unselect the button using jQuery

I want to trigger a popover when a variable exceeds a certain value, triggered by clicking a button: $(function () { $('[data-toggle="tooltip"]').tooltip({ trigger: 'manual', placement: 'top', titl ...

If the item has an active class, apply a new class to the parent element and all of its

If I have code like the example below and want to add the show class to the parent and ancestors. // The last `nav-item` has the `active` class <div class="nested-group nested-item show"> <div class="nested-item show"> <div class="n ...

I am unable to execute two queries simultaneously on a node

Here is the code snippet I've been working on: app.get('/listuser/:id', function (req, res) { Utenti.find().then(listut => {res.render('listuser',{listut: listut}) }) Utenti.findOne({ _id: req.user.id }, function (err, obj ...

Tips for capturing the interaction between a jQuery Dialog and its Parent

Within the parent HTML, there is a call that triggers a JavaScript function. <div class="data"> <form:input title="Building" styleClass="content contractorDisable" maxlength="5" size="6" path="fireImpairForm.bldCode" />&nbsp; <a hre ...

open channel for app communication: express

I am currently working on creating a basic chat application using node.js with Express. The versions I am using are v0.12.7 for Node and 4.13.1 for Express. I am facing an issue with accessing the port that my application is listening to, despite conduct ...

Leveraging a tool to dynamically modify the styles of the active elements based on user interactions

My goal is to enhance the flexibility of my service by enabling it to handle any input field dynamically. Currently, I find myself manually coding everything, which is becoming quite labor-intensive. Is there a way to pass the element object when the eleme ...

Tips for avoiding duplicate documents in MongoDB using Mongoose

In the database, I have two collections - one for users and one for portfolios on MongoDB. The portfolio model contains a reference to the object id of the user collection. I am currently working on implementing a feature where if a logged-in user tries to ...

Incorporating Next and Previous navigation buttons to my slideshow

I'm looking to enhance my image slider by including next and previous buttons, but I'm unsure of how to proceed. Can anyone provide guidance or assistance with this? Below is the basic structure that I currently have in place: Here is the code s ...

What is the reason behind my difficulty in opening my dialog box modally using JavaScript?

I am looking to keep a dialog open while data is being fetched from the server. Here is the code I have written: (async()=>{ document.getElementById("dialog").showModal(); if(condition1 is true){ await server_call1(); } ...

Return an array that has been filtered to exclude any elements that are also found in a separate array

I have an API that provides a list of cars. const getAsset = async () => dbApi('list_cars', ['', 100]) .then(result => result.map(e => e.symbol)); Here, the function getAsset returns the car list. 0: "BMW" 1: "HONDA" 2: " ...

Setting up the react-ultimate-pagination component

I've been experimenting with the react-ultimate-pagination package available at: https://github.com/ultimate-pagination/react-ultimate-pagination My goal is to configure it in a way similar to their basic demo showcased here: https://codepen.io/dmytr ...

Step-by-step guide on extracting checkbox value from response in Angular JS

Successfully added a checkbox value to the database. An issue arises when checking a checkbox after receiving a response, as the checked value displays as -1 instead of 0, 1, or 2. When clicking on a checked box, its index value should change to -1, bu ...

Exploring JSON data with React Native

When I send a JSON request, I receive a response with JSON objects; { "kind": "youtube#searchListResponse", "etag": "zy8y9DkaOiYwKh0aStoEqOU_knU", "nextPageToken": "CBQQAA", "regionCode": "GB", "pageInfo": { "totalResults": 40, "results ...