即使我设置了 CORS 原点,也会不断收到 CORS 错误
Posted
技术标签:
【中文标题】即使我设置了 CORS 原点,也会不断收到 CORS 错误【英文标题】:Access from origin 'https://example.com' has been blocked even though I've allowed https://example.com/ 【发布时间】:2022-01-18 01:13:46 【问题描述】:我有一个使用 React、Node.js 和 Socket.io 制作的应用 我将 Node 后端部署到 heroku,前端部署到 Netlify
我知道 CORS 错误与服务器有关,但无论我添加什么,它都无法通过下图中的错误。 我还将代理脚本添加到 React 的 package.json 作为“代理”:“https://googledocs-clone-sbayrak.herokuapp.com/”这是我的server.js
文件;
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.listen(process.env.PORT || 5000, () =>
console.log(`Server has started.`)
);
这是我从前端发出请求的地方;
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 */
【问题讨论】:
https://googledocs-clone-sbayrak.netlify.app/
不是来源。删除尾部斜杠。
我现在重新部署了,它可以工作了!谢谢你。你能解释一下为什么它以前不起作用吗?
在下面查看我的回复。
【参考方案1】:
TL;DR
https://googledocs-clone-sbayrak.netlify.app/
不是origin。删除尾部斜杠。
有关问题的更多详细信息
Origin
标头的值中不允许有斜杠
根据 CORS 协议(在Fetch standard 中指定),browsers never set the Origin
request header to a value with a trailing slash。因此,如果https://googledocs-clone-sbayrak.netlify.app/whatever
的页面发出跨域请求,则该请求的Origin
标头将包含
https://googledocs-clone-sbayrak.netlify.app
没有任何尾随斜杠。
服务器端逐字节比较
您正在使用Socket.IO、which relies on 和Node.js cors
package。如果请求的来源与您的 CORS 配置的 origin
值 (https://googledocs-clone-sbayrak.netlify.app/
) 不完全匹配,该包将不会在响应中设置任何 Access-Control-Allow-Origin
。
把它们放在一起
显然,
'https://googledocs-clone-sbayrak.netlify.app' ===
'https://googledocs-clone-sbayrak.netlify.app/'
评估为false
,这会导致cors
包未在响应中设置任何Access-Control-Allow-Origin
标头,这会导致浏览器中的CORS 检查失败,从而导致您观察到CORS 错误。
【讨论】:
我现在明白了,谢谢!【参考方案2】:看起来你还没有导入 cors 包。是在其他地方进口的吗?
var cors = require('cors') // is missing
【讨论】:
就在那里,app.use(cors())
感谢您的通知,我已添加但仍然收到错误
app.use(cors())
是使用 cors 包。但它没有被导入,你需要 const cors = require('cors')
。请试试这个。
是的,我已经进口了 cors,它不见了;真的。我重新部署了,但还是不行
能否尝试注释掉socket.io相关的代码,只保留app.use(cors())。这可能有效。以上是关于即使我设置了 CORS 原点,也会不断收到 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章
即使在配置 ASP.NET Core Web API 中启用了 CORS,CORS 也会阻止发布请求
即使启用了通过 JavaScript 加载的图像,也会向我抛出 CORS 错误