首頁  >  問答  >  主體

從來源“https://example.com”訪問即使我允許 https://example.com/ 也被阻止

我有一個使用 React、Node.js 和 Socket.io 製作的應用程式

# 我將 Node 後端部署到 heroku ,前端部署到 Netlify

#


我知道 CORS 錯誤與伺服器有關,但無論我添加什麼,它都無法解決下圖中的錯誤。

我還在 React 的 package.json 中添加了代理腳本作為“proxy”:“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.lis ten(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 */
 }


#
P粉805922437P粉805922437310 天前516

全部回覆(2)我來回復

  • P粉038856725

    P粉0388567252023-12-15 15:50:11

    看來您還沒有匯入 cors 套件。是從其他地方進口的嗎?

    var cors = require('cors') // is missing

    回覆
    0
  • P粉674876385

    P粉6748763852023-12-15 10:51:51

    TL;DR

    https://googledocs-clone-sbayrak.netlify.app/不是起源。刪除結尾的斜線。

    有關問題的更多詳細資訊

    Origin 標頭的值中不允許有尾部斜線

    根據CORS協定(在Fetch標準中指定),瀏覽器永遠不會將Origin 請求標頭設定為帶有尾部斜線的值。因此,如果 https://googledocs-clone-sbayrak.netlify.app/whatever 上的頁面發出跨來源請求,則該請求的 Origin 標頭將包含

    https://googledocs-clone-sbayrak.netlify.app

    沒有任何尾部斜線。

    伺服器端逐字節比較

    您正在使用Socket.IO依賴 節點.js cors 套件。如果要求的來源與您的 CORS 配置的 origin 值 (https ://googledocs-clone-sbayrak.netlify.app/)。

    把它們放在一起

    顯然,

    'https://googledocs-clone-sbayrak.netlify.app' ===
        'https://googledocs-clone-sbayrak.netlify.app/'
    

    評估為false,這會導致cors套件不在回應中設定任何Access-Control-Allow-Origin標頭,這導致瀏覽器中的CORS 檢查失敗,因此出現您觀察到的CORS 錯誤。

    取得標準範例

    Fetch 標準的第 3.2.5 節甚至提供了 這個錯誤的一個有啟發性的例子

    Access-Control-Allow-Origin: https://rabbit.invalid/
    

    並解釋了為什麼它會導致 CORS 檢查失敗:

    回覆
    0
  • 取消回覆