【问题标题】:Socket.io + Nodejs + Angular2+ - CORS header 'Access-Control-Allow-Origin' missingSocket.io + Node Js + Angular 2 - 缺少 CORS 标头“Access-Control-Allow-Origin”
【发布时间】:2019-02-04 04:38:59
【问题描述】:

我正在做一个 MEAN 堆栈应用程序。为了在客户端和服务器之间进行通信,我使用了一些 HTTP 请求和 websocket。在本地主机上它工作正常。

但是,当我尝试将应用程序从 localhost 部署到特定服务器时,websockets 不再工作。但是,http 请求可以正常工作。

我收到了这个警告:

跨域请求被阻止:同源策略不允许读取 远程资源在 http://138.250.31.29/socket.io/?userId=5b7c030dca40486dabaafaaf&EIO=3&transport=polling&t=MM5TZt_。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

为了建立连接,我在 Node.JS 上有两个文件:

APP.JS

const createError = require("http-errors");
const express = require("express");
const path = require("path");
const logger = require("morgan");
const favicon = require("serve-favicon");
const cors = require("cors");

require("./models/db");
require("./config/passport");

const passport = require("passport");
const apiRouter = require("./routes/index");

const corsOptions = {
  origin: "*",
  optionsSuccessStatus: 200
};

const app = express();

app.use(logger("dev"));
app.use(express.json({ limit: "1gb" }));
app.use(express.urlencoded({ extended: false }));
app.use(passport.initialize());
app.use(cors(corsOptions));
app.use("/api", apiRouter);

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
  next();
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});

// error handlers
// Catch unauthorised errors
app.use(function(err, req, res, next) {
  if (err.name === "UnauthorizedError") {
    res.status(401);
    res.json({ message: err.name + ": " + err.message });
  }
});

module.exports = app;

万维网

!/usr/bin/env node

/**
 * Module dependencies.
 */

const app = require("../app");
const debug = require("debug")("sorfml:server");
const http = require("http");
const socketIO = require("socket.io");

/**
 * Get port from environment and store in Express.
 */

const port = normalizePort(process.env.PORT || "3000");
app.set("port", port);

/**
 * Create HTTP server.
 */

const server = http.createServer(app);

/**
 * Bind the socket.IO with the http server
 */
const io = socketIO(server);
io.origins("*:*");

clientsList = {};

/**
 * Socket connection
 */
io.on("connection", socket => {
  console.log("Client connected " + socket.id);
  socket.user_id = socket.handshake.query.userId;
  clientsList[socket.handshake.query.userId] = socket;

  socket.on("disconnect", () => {
    delete clientsList[socket.user_id];
    console.log("Client disconnected: " + socket.id);
  });
});

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on("error", onError);
server.on("listening", onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  const port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== "listen") {
    throw error;
  }

  const bind = typeof port === "string" ? "Pipe " + port : "Port " + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case "EACCES":
      console.error(bind + " requires elevated privileges");
      process.exit(1);
      break;
    case "EADDRINUSE":
      console.error(bind + " is already in use");
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  const addr = server.address();
  const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
  console.log("Listening on " + bind);
}

在客户端(Angular):

import * as io from "socket.io-client";


    private socket;
    this.socket = io("ws://138.250.31.29/sorfml_api", { query: "userId=" + userId });

    this.socket.on("sendNotification", data => {
     // Do a function
    });

    this.socket.on("deleteNotificationFromAuthor", data => {
      // Do a function
    });

我在 Stackoverflow 和 Github 上发现了很多关于它的问题,但没有解决我的问题。

我尝试像这样设置原点(在 www 文件中):

io.set('origins', '*:*');

io.set('origins', 'http://138.250.31.29:80');

然后在 app.js 文件中,我还尝试在 corsOptions 和 app.use() 中添加更多授权。但没有任何效果。

【问题讨论】:

    标签: node.js angular websocket socket.io cors


    【解决方案1】:

    试试cors。示例:

    var cors = require('cors')
    var app = express()
    
    app.use(cors())
    

    说明:您必须在节点服务器的 http 标头上启用 CORS。

    【讨论】:

    • 实际上在代码中,在 app.js 中。常量 cors = 要求(“cors”);常量应用程序 = 快递(); app.use(cors(corsOptions));
    【解决方案2】:

    我猜你的io.set('origins', ':'); 声明是错误的,

    应该是,

    io.set('origins', '*:*');
    

    io.origins('*:*')
    

    希望这会有所帮助!

    【讨论】:

    • 根据您使用的 socket.io 版本,io.set 可能不可用。在文档中使用类似的东西(注意数组类型参数):socket.io/docs/server-api/#server-origins-valuecc/@PierBJX
    • 我在 node.js 上使用 socket.io v2.1.1,在 angular 上使用 socket.io-client v2.1.1。我添加了这个,但我在服务器上看不到任何 console.log: io.origins((origin, callback) => { if (origin !== 'foo.example.com') { console.log("Error Origin") ; return callback('origin not allowed', false); } console.log("Going through") callback(null, true); });
    猜你喜欢
    • 2018-03-28
    • 2019-02-07
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 2021-12-07
    • 2023-03-21
    相关资源
    最近更新 更多