出现 No Access-Control-Allow-Origin cors 错误,但标头已设置并且在本地环境中工作正常,但无法在 render.com 上实时工作

问题描述 投票:0回答:4

总结:我在 Nodejs 后端上使用 cors npm,并且能够在本地计算机上成功地在与后端分开的端口上从前端发出请求。在生产中,我收到一个 cors 错误,指出未设置 Access-Control-Allow-Origin。我的 sever.js 文件包含在最后。谢谢!

完整解释:

我有一个带有单独后端文件夹和前端文件夹的应用程序。后端是用nodejs构建的。前端是reactjs,并且正在成功从 localhost:3000 到 localhost:5000 上运行的后端服务器进行 axios 调用。当我在本地运行时检查 Chrome 浏览器中的元素时,它显示后端已成功“设置”的 Access-Control-Allow-Origin 标头。

在新的 render.com 网站上的生产中,我的前端位于静态 render.com 应用程序上,后端位于 render.com Web 服务应用程序上。两者都作为单独的应用程序工作/运行良好,但是当前端对后端进行任何 api 调用时,它会收到 No Access-Control-Allow-Origin 错误。当我检查网络标头下的 chrome 检查时,它没有显示像在本地环境中那样设置的 Access-Control-Allow-Origin。

我尝试重建前端和后端以清除缓存,但没有成功。我已将 Access-Control-Allow-Origin 标头设置为“*”,只是为了让它显示在实时环境中,但没有成功。我尝试了以下几种但没有成功:

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");
  next();
});

还有:

app.use(
  cors({
    origin: "*",
    methods: ["GET", "POST", "DELETE", "UPDATE", "PUT"],
    credentials: true,
  })
);

这些方法都不起作用。我确保这一切都是在 server.js 文件中运行路由之前完成的,因为我可以将它们放入该文件中。

chrome 检查工具上的本地标头屏幕截图:

生产标头:

这是我的 server.js 文件,它尝试设置标头并设置 cors npm 包。我留下了几个注释掉的测试,只是为了展示我测试过的一些东西。当前的测试是我尝试让 cors npm 包设置标头:

const http = require('http');
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const bodyParser = require('body-parser');
const path = require('path');
const request = require('request')
const cookieParser = require("cookie-parser");
const session = require('express-session');
const MongoDBSession = require('connect-mongodb-session')(session);

require('dotenv').config();

const app = express();

// app.use(function(req, res, next) {
//   res.setHeader("Access-Control-Allow-Origin", "*");
//   next();
// });

// 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");
//   next();
// });

// app.get('/*',function(req,res,next){
//   res.header('X-XSS-Protection' , 0 );
//   next(); // http://expressjs.com/guide.html#passing-route control
// });

// app.use(cors())

//actual connection to the mongodb server
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true }
);
const connection = mongoose.connection;
connection.once('open', () => {
  console.log("MongoDB database connection established successfully");
})

const store = new MongoDBSession({
  uri: uri,
  collection: 'mySessions',
});

app.use(express.json());
app.use(express.urlencoded({
  extended: true
}));

let allowUrls = "*"

app.use(
  cors({
    origin: allowUrls,
    methods: ["GET", "POST", "DELETE", "UPDATE", "PUT"],
    credentials: true,
    // allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'device-remember-token', 'Access-Control-Allow-Origin', 'Origin', 'Accept']
  })
);


// app.use(cors())
// app.options('*', cors());
// 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");
//   next();
// });

app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: false})); //Post Body Parser

app.use(
  session({
    key: "userId",
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
      expires: 365 * 24 * 60 * 60 * 1000,
    },
    store: store,
  })
);

// app.use(cors());
// app.use(cors({
//   origin: 'http://localhost:3000',
//   methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD'],
//   credentials: true
// }));

const example = require('./routes/example');
//... lots more routes here

app.use('/example', example);
//... more here

app.get('/', (req, res) => {
  console.log('hit get request for /: ', res)
  res.sendStatus(200)
})

const port = !process.env.NODE_ENV ? 5000 : process.env.PORT;

app.listen(port, () => {
  console.log(`Server is running on port: ${port} process.env.NODE_ENV = ${process.env.NODE_ENV}`);
});
node.js reactjs cors render.com
4个回答
4
投票

我想通了。我放弃了 cors npm 并只使用 res.header 方法,因为我的主要问题是我可以弄清楚如何让 cors 设置原始标头:

app.use(function(req, res, next) {
      // res.header("Access-Control-Allow-Origin", "*");
      const allowedOrigins = ['http://localhost:3000', 'http://gamebrag.onrender.com', 'https://gamebrag.onrender.com'];
      const origin = req.headers.origin;
      if (allowedOrigins.includes(origin)) {
           res.setHeader('Access-Control-Allow-Origin', origin);
      }
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
      res.header("Access-Control-Allow-credentials", true);
      res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, UPDATE");
      next();
    });

确保它尽可能高,但之后

const app = express();

我猜我不小心将

app.use(cors())
包含在 res.headers 中,这也把事情搞砸了。 Render.com 在俄勒冈/美国西部地区的免费网络服务也存在问题,我通过在美国东部创建一个新的免费网络服务解决了这个问题。


0
投票

我的渲染后端也有同样的问题。我正在编辑“Content-Length”响应标头,以将文件大小传达给我的前端以获取下载进度。

    res.set("Content-Length", `${fileSize}`); //bad. causes cors issue

当我删除这一行时,cors 策略错误就消失了。 我通过使用自定义标头并使用“Access-Control-Expose-Headers”公开它来解决这个问题。我是新人,所以我不确定这是否是不好的做法。

    res.set({ "Access-Control-Expose-Headers": "X-File-Size" });
    res.set("X-File-Size", `${fileSize}`);

0
投票

你好,我有完全相同的问题,但我不明白是如何解决的,你能指导我吗


-1
投票

如果您的项目中没有依赖项限制,您可以尝试 Cors https://www.npmjs.com/package/cors

© www.soinside.com 2019 - 2024. All rights reserved.