I have an app made using React, Node.js and Socket.io
I deployed the Node backend to heroku and the frontend to Netlify
I know the CORS errors are related to the server, but no matter what I add, it doesn't resolve the error in the picture below.
I also added the proxy script as "proxy" in React's package.json: "https://googledocs-clone-sbayrak.herokuapp.com/"
This is my server.js
file;
const mongoose = require('mongoose'); const Document = require('./Document'); const dotenv = require('dotenv'); const path = require('path'); const express = require('express'); const http = require('http'); const socketio = require('socket.io'); dotenv.config(); const app = express(); app.use(cors()); const server = http.createServer(app); const io = socketio(server, { cors: { origin: 'https://googledocs-clone-sbayrak.netlify.app/', methods: ['GET', 'POST'], }, }); app.get('/', (req, res) => { res.status(200).send('hello!!'); }); const connectDB = async () => { try { const connect = await mongoose.connect(process.env.MONGODB_URI, { useUnifiedTopology: true, useNewUrlParser: true, }); console.log('MongoDB Connected...'); } catch (error) { console.error(`Error : ${error.message}`); process.exit(1); } }; connectDB(); let defaultValue = ''; const findOrCreateDocument = async (id) => { if (id === null) return; const document = await Document.findById({ _id: id }); if (document) return document; const result = await Document.create({ _id: id, data: defaultValue }); return result; }; io.on('connection', (socket) => { socket.on('get-document', async (documentId) => { const document = await findOrCreateDocument(documentId); socket.join(documentId); socket.emit('load-document', document.data); socket.on('send-changes', (delta) => { socket.broadcast.to(documentId).emit('receive-changes', delta); }); socket.on('save-document', async (data) => { await Document.findByIdAndUpdate(documentId, { data }); }); }); console.log('connected'); }); server.lis ten(process.env.PORT || 5000, () => console.log(`Server has started.`) );
This is where I make requests to the front end;
import Quill from 'quill'; import 'quill/dist/quill.snow.css'; import { useParams } from 'react-router-dom'; import { io } from 'socket.io-client'; const SAVE_INTERVAL_MS = 2000; const TextEditor = () => { const [socket, setSocket] = useState(); const [quill, setQuill] = useState(); const { id: documentId } = useParams(); useEffect(() => { const s = io('https://googledocs-clone-sbayrak.herokuapp.com/'); setSocket(s); return () => { s.disconnect(); }; }, []); /* below other functions */ /* below other functions */ /* below other functions */ }
It seems that you have not imported the cors package. Is it imported from somewhere else?
TL;DR
https://googledocs-clone-sbayrak.netlify.app/
is not origin. Remove the trailing slash.More details about the problem
Origin
Trailing slashes are not allowed in header valuesAccording to the CORS protocol (specified in the Fetch standard ), the browser will never set the
Origin
request header to a value with a trailing slash . So if the page athttps://googledocs-clone-sbayrak.netlify.app/whatever
makes a cross-origin request, the request'sOrigin
header will contain p>without any trailing slash.
Server-side byte-by-byte comparison
You are using Socket.IO, which depends on the node.js
cors
package . If the origin of the request matches theorigin
value of your CORS configuration (https://googledocs-clone-sbayrak.netlify.app/
).Put them together
Obviously,
evaluates to
false
, which causes thecors
package to not set anyAccess-Control-Allow-Origin
headers in the response, which causes the browser to The CORS check failed, hence the CORS error you observed.Get standard examples
Section 3.2.5 of the Fetch standard even provides an instructive example of this error ,
And explains why it causes CORS checks to fail: