【问题标题】:Express.js and CORSExpress.js 和 CORS
【发布时间】:2021-12-29 01:53:22
【问题描述】:

我使用react.js 构建了一个前端,并使用express.js 构建了一个API 服务器。为了处理 CORS,我使用了 cors 包作为以下示例:

var passport = require("passport");
const express = require('express');
const cors = require('cors');

const app = express();
app.use(cors());
app.use('/route1', passport.authenticate('jwt', {session: false}), route1)
app.use('/route2', passport.authenticate('jwt', {session: false}), route2)
app.use('/route3', passport.authenticate('jwt', {session: false}), route3)

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

app.listen(app.get('port'), () => {    
  logger.info('Server started')
})  

所有路由都运行良好,直到一个请求对同一路由发出两个连续请求。例如:

POST example.com/route1
GET example.com/route1

对于 GET 请求,我将在浏览器控制台中收到错误 No 'Access-Control-Allow-Origin' header is present on the requested resource.。但是,如果我将路线的路径更改为,例如:

POST example.com/route1
GET example.com/route1/example

它有效。

两台服务器都在 apache 网络服务器上运行。我的后端服务器通过 https 访问,它将其重定向到运行在 http 上的 nodejs 服务器。

我做错了什么?谢谢。

编辑:按照要求,这是route1的sn-p

const express = require('express')
const router = express.Router()
const errors = require('./error_handler');

router.post('/', async (req, res, next) => {
    const result = 
        /* DB Middleware */
        .catch((err) => errors.errorHandler(err,res))

    if(!res.headersSent) /* Making this condition to check if errorHandler() already sent an error response */
        res.send(result);
})

router.get('/', async (req, res, next) => {
    if(req.query.course === undefined)
        res.send(400);  


    let result =
        /* DB Middleware */
        .catch((err) => errors.errorHandler(err,res))

    
    if(!res.headersSent)
        res.send(result)
})

module.exports = router

【问题讨论】:

  • 你能分享一个来自 route1 文件的代码 sn-p 吗?
  • 刚刚用它的 sn-p 进行了编辑
  • 嗨@spacecows,确认apache严重正在将所有响应头从在http上运行的node.js应用程序转发到在浏览器上运行的客户端
  • @oseme_techguy 我不是管理员,但我会尽快与他核实。但如果这是原因,它不会在其他所有情况下都失败,而不仅仅是在特定情况下吗?
  • 从这里的包描述来看-> npmjs.com/package/cors 默认配置相当于:``` { "origin": "*", "methods": "GET,HEAD,PUT, PATCH,POST,DELETE", "preflightContinue": false, "optionsSuccessStatus": 204 } ``` 这意味着默认配置不会处理使用/需要 OPTION 动词或预检的情况。

标签: node.js express cors backend


【解决方案1】:

前段时间我在一个项目中遇到了这个问题,我将它添加到我的应用程序中,并为我工作。这是因为您需要允许每个来源访问您的项目。

app.use(function (req, res, next) {
    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');
    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
});

如果不起作用,请尝试将 crossDomain 添加到您的请求中,例如:

 $.ajax({
    url: url,
    crossDomain: true,
    data: form,
    dataType: 'json',
    success: function(data) {
        console.log(data);
    },
    type: 'POST'
});

【讨论】:

  • 我昨天尝试了那个解决方案,我现在尝试了只是为了确定,但现在每个请求都会收到错误No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • 还是跨域?
  • 我是 axios 而不是 ajax,所以我尝试使用跨域 asaxios.defaults.crossDomain = true,但它也不起作用。
【解决方案2】:

在 app.js 中包含以下代码:

var express = require('express')
var cors = require('cors')
var app = express()
var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}
app.use(cors(corsOptions));

您可以创建一个通用中间件,该中间件将用于您想要支持 cors 的任何 API。

var AllowedOrigins = ['http://example1.com', 'http://example2.com'];
setCorsHeaders: function (req, res, next) {
    let requestDomain = req.headers.Origin;
     AllowedOrigins.forEach(allowedOrigin => {
         if (requestDomain === allowedOrigin) {
            res.setHeader('Access-Control-Allow-Origin', requestDomain);
            res.setHeader('Access-Control-Allow-Credentials', true);
            res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
         }
     });
     if (req.method === 'OPTIONS') {
        res.status(200);
     } else {
        next();
     }
}

【讨论】:

    猜你喜欢
    • 2012-07-28
    • 2017-07-25
    • 2020-11-25
    • 2021-12-18
    • 2019-07-18
    • 1970-01-01
    • 2016-03-10
    • 2019-01-16
    • 2020-06-23
    相关资源
    最近更新 更多