Nginx

Nginx 伺服器塊和 socket.io - CORS

  • February 20, 2021

一段時間以來,我一直在使用這種伺服器塊結構執行應用程序,但它從未給我帶來任何問題。

geo $authentication {
 default "Authentication required";
 `Some ip number` "off";
}

server {
 listen         80 default_server;
 listen    [::]:80 default_server;
 server_name my.domain.com;
 return 301 https://$host$request_uri;
}

server {
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
 ssl_certificate /etc/letsencrypt/live/my.domain.com/fullchain.pem; # managed by Certbot
 ssl_certificate_key /etc/letsencrypt/live/my.domain.com/privkey.pem; # managed by Certbot

 include /etc/letsencrypt/options-ssl-nginx.conf;
 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

 server_name my.domain.com;
 client_max_body_size 200M;
 
 root /var/www/;
 index index.php index.html index.htm;

 location / {
   add_header Access-Control-Allow-Origin *;
   auth_basic $authentication;
   auth_basic_user_file /var/www/.htpasswd;
   try_files $uri $uri/ =404;
 }

 # Here is for example the app where I am running socket.io from
 location /myapp {
   auth_basic $authentication;
   auth_basic_user_file /var/www/.htpasswd;
   try_files $uri $uri/ =404;
 }

 # If this app has some sort of api route for express I do a proxy pass
 location /api/upload/ {
   proxy_pass http://localhost:5003/api/upload;
 }

但是,我正在嘗試使用 socket.io,但我無法理解子文件夾是否有問題,因為如果我嘗試從客戶端連接,我會不斷收到 CORS

import { io } from 'socket.io-client'
const socket = io('http://localhost:5003')

在伺服器上我得到了這個

import express from 'express'
import { createServer } from 'http'
import { Server } from 'socket.io'

const app = express()
const prod = process.env.NODE_ENV === 'production'
const port = process.env.PORT || prod ? 5003 : 4000
const httpServer = createServer(app)

const io = new Server(httpServer, {
 cors: {
   origin: '*',
   methods: ['GET', 'POST']
 }
})

const connections = []

io.on('connection', (socket) => {
 connections.push(socket)
 console.log(`Socket id ${socket.id} connected`)

 socket.on('disconnect', () => {
   connections.splice(connections.indexOf(socket), 1)
 })
})

httpServer.listen(port, () => console.log(`App listening on port ${port}.`))

我可以看到,雖然在開發過程中一切正常,並且它建立了一個 Web 套接字連接:

在此處輸入圖像描述

在 CORS 之後的伺服器上,它當然不會:

在此處輸入圖像描述

無論我嘗試什麼,我總是最終得到這個: 在此處輸入圖像描述

在您的第二張圖片中,socket.io 庫正在使用輪詢。這可能是因為您沒有正確設置 nginx 配置。

location /socket.io/ {
   proxy_pass http://localhost:5003/socket.io/;
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "Upgrade";
   proxy_set_header Host $host;
}

是一個很好的例子。更改此設置後,您應該能夠使用以下命令訪問您的後端:

import { io } from 'socket.io-client'
const socket = io()

請注意,如果您的所有請求都通過 Nginx,則不需要 CORS 指令,因為您的所有請求都將發送到相同的地址和埠。

引用自:https://serverfault.com/questions/1054250