-1

I'm currently learning how to create a chat app using Node and express for the backend and react for the frontend but am having a CORS error.

I'm getting this errror below because of CORS, however, I have implemented every CORS I can on the app.

This is the error

:3001/chat?name=jaden&room=love:1 Access to XMLHttpRequest at 'http://localhost:8000/socket.io/?EIO=4&transport=polling&t=NOYd8LK' from origin 'http://127.0.0.1:3001' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:3001' that is not equal to the supplied origin.
polling-xhr.js:203 GET http://localhost:8000/socket.io/?EIO=4&transport=polling&t=NOYd8LK net::ERR_FAILED
create @ polling-xhr.js:203
Request @ polling-xhr.js:120
request @ polling-xhr.js:63
doPoll @ polling-xhr.js:92
poll @ polling.js:76
doOpen @ polling.js:23
open @ transport.js:43
open @ socket.js:170
Socket @ socket.js:94
push../node_modules/component-emitter/index.js.Emitter.emit @ index.js:145
onError @ polling-xhr.js:246
(anonymous) @ polling-xhr.js:196
setTimeout (async)
xhr.onreadystatechange @ polling-xhr.js:195
:3001/chat?name=jaden&room=love:1 Access to XMLHttpRequest at 'http://localhost:8000/socket.io/?EIO=4&transport=polling&t=NOYd9p5' from origin 'http://127.0.0.1:3001' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:3001' that is not equal to the supplied origin.
polling-xhr.js:203 GET http://localhost:8000/socket.io/?EIO=4&transport=polling&t=NOYd9p5 net::ERR_FAILED

This is the backend Code

const express = require('express')
const http = require('http')
const socketIo = require('socket.io')
const cors = require('cors')

const app = express()

app.use(cors())

const server = http.createServer(app)

const io = socketIo(server, {
  cors: {
        origin: "http://localhost:3001",
        methods: ["GET", "POST"]
      }
})

// Listening for a connection on the socket.io server

io.on('connection', (socket)=>{
  // the moment i get a connection, i want to send a welcome message
  socket.on('join', ({name, room})=>{
    socket.emit('message', {user:'admin', text:`${name}, You're welcome!`})
    socket.broadcast.emit('message', {user:'admin', text:`${name}, just joined`})
    console.log('welcome message')
  })

  socket.on('sendMessage', (message)=>{
    io.emit('message', {user:'user', text:message})
  })

  socket.on("disconnect", ()=>{
    io.emit('message', {user:'admin', text:`user Just left!`})
  })

})


const port = process.env.PORT || 8000
server.listen(port, ()=> console.log(`Listening on port : ${port}`))

  • I tried your code and connected from `localhost:80` using `var socket = io("localhost:8000");` and it worked on the spot, even with your cors options. I removed them and it still worked fine as-is. (also, if you're following an online tutorial you should always link to it in the question) –  Dec 02 '20 at 09:00
  • Someone told me to remove the localhost from the connection and use 127.0.0.1 instead, strangely, I did it and the code started working. I thought localhost is the same thing as 127.0.0.1. That has really confused me now. – lovelyn marshall Dec 02 '20 at 09:12
  • It's basically the same thing, yes. It makes no difference for me; adding cors code isn't necessary with socket.io anyway. Remove all cors code and it should just work. You can also use the same server that serves your website for socket.io; when you publish the website you have to do that anyway. –  Dec 02 '20 at 09:23

2 Answers2

0

Localhost isn't the actual origin. The origin ip address is 127.0.0.1 and so change the origin from http://localhost:3001 to http://127.0.0.1:3001.

const io = socketIo(server, {
      cors: {
        origin: "http://127.0.0.1:3001",
        methods: ["GET", "POST"]
      }
})
Abir Taheer
  • 2,502
  • 3
  • 12
  • 34
  • Thanks, this has worked but I still don't understand it because I thought localhost means the same as 127.0.0.1 – lovelyn marshall Dec 02 '20 at 09:06
  • This question might help understand the difference between localhost and 127.0.0.1 https://stackoverflow.com/questions/7382602/what-is-the-difference-between-127-0-0-1-and-localhost I've looked into the socket.io code and it looks like it's using the cors package. In the index file of the cors package if you look at lines 27-28, if you provide it a string it'll just do an equality comparison. https://github.com/expressjs/cors/blob/5c0b6c7a0cbf126c949b9a76c7c67e26eba6b3e1/lib/index.js#L27-L28 – Abir Taheer Dec 02 '20 at 09:19
0

Because you are calling from the IP 127.0.0.1 not the localhost, and node server cannot distinguish localhost and 127.0.0.1. In fact, origin can accept a function, so you can change to this


let whitelist = [
    'http://127.0.0.1:3001', // dev
    'http://localhost:3001', // dev
    // any others url
]

const io = socketIo(server, {
    cors: {
        origin: function (origin, callback) {
            if (whitelist.indexOf(origin) > -1) {
                callback(null, true)
            } else {
                callback(null, false)
            }
        },
        methods: ["GET", "POST"]
    }
})
chonnychu
  • 1,068
  • 6
  • 10