首页 文章

如何允许CORS?

提问于
浏览
520

我试图在我的Node.js应用程序中支持使用Express.js Web框架的CORS . 我已阅读a Google group discussion关于如何处理这个问题,并阅读了一些关于CORS如何工作的文章 . 首先,我这样做了(代码是用CoffeeScript语法编写的):

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

它似乎不起作用 . 好像我的浏览器(Chrome)没有发送初始OPTIONS请求 . 当我刚刚更新资源块时,我需要将跨源GET请求提交到:

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

它有效(在Chrome中) . 这也适用于Safari .

我读过......

在实现CORS的浏览器中,每个跨源GET或POST请求前面都有一个OPTIONS请求,用于检查GET或POST是否正常 .

所以我的主要问题是,为什么我的情况似乎没有发生?为什么我的app.options块没有被调用?为什么我需要在主app.get块中设置 Headers ?

22 回答

  • 109

    可以参考下面的代码相同 . 资料来源:Academind/node-restful-api

    const express = require('express');
    const app = express();
    
    //acts as a middleware
    //to handle CORS Errors
    app.use((req, res, next) => { //doesn't send response just adjusts it
        res.header("Access-Control-Allow-Origin", "*") //* to give access to any origin
        res.header(
            "Access-Control-Allow-Headers",
            "Origin, X-Requested-With, Content-Type, Accept, Authorization" //to give access to all the headers provided
        );
        if(req.method === 'OPTIONS'){
            res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET'); //to give access to all the methods provided
            return res.status(200).json({});
        }
        next(); //so that other routes can take over
    })
    
  • 10

    我们可以避免使用CORS并将请求转发给其他服务器:

    // config:
    var public_folder = __dirname + '/public'
    var apiServerHost = 'http://other.server'
    
    // code:
    console.log("starting server...");
    
    var express = require('express');
    var app = express();
    var request = require('request');
    
    // serve static files
    app.use(express.static(public_folder));
    
    // if not found, serve from another server
    app.use(function(req, res) {
        var url = apiServerHost + req.url;
        req.pipe(request(url)).pipe(res);
    });
    
    app.listen(80, function(){
        console.log("server ready");
    });
    
  • 3

    做这样的事情:

    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();
    });
    
  • -2

    除了其他人所说的,不要忘记,除非使用nodemon,否则您需要重新启动节点服务器才能使更改生效!

    我个人一直习惯于刷新我的浏览器,忘记它是服务器端代码 .

  • 408

    使用Express Middleware对我来说很有用 . 如果您已经在使用Express,只需添加以下中间件规则即可 . 它应该开始工作 .

    app.all("/api/*", function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
      res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
      return next();
    });
    
    app.all("/api/*", function(req, res, next) {
      if (req.method.toLowerCase() !== "options") {
        return next();
      }
      return res.send(204);
    });
    

    Reference

  • 53

    下面的代码可以使用,但首先安装cors:

    npm install --save cors

    然后:

    module.exports = function(app) { 
    var express = require("express");
    var cors = require('cors');
    var router = express.Router();
    app.use(cors());
    
    app.post("/movies",cors(), function(req, res) { 
    res.send("test");
    });
    
  • 29

    尝试将控制权传递给下一个匹配的路线 . 如果Express首先匹配app.get路由,那么它将不会继续到选项路由,除非你这样做(注意使用next):

    app.get('somethingelse', function(req, res, next) {
        //..set headers etc.
    
        next();
    });
    

    在组织CORS的方面,我把它放在一个适合我的中间件中:

    //CORS middleware
    var allowCrossDomain = function(req, res, next) {
        res.header('Access-Control-Allow-Origin', 'example.com');
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        res.header('Access-Control-Allow-Headers', 'Content-Type');
    
        next();
    }
    
    //...
    app.configure(function() {
        app.use(express.bodyParser());
        app.use(express.cookieParser());
        app.use(express.session({ secret: 'cool beans' }));
        app.use(express.methodOverride());
        app.use(allowCrossDomain);
        app.use(app.router);
        app.use(express.static(__dirname + '/public'));
    });
    
  • 47

    在不同端口中使用快速节点离子运行进行测试 .

    Localhost:8100

    Localhost:5000

    // CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
    
    app.all('*', function(req, res, next) {
           res.header("Access-Control-Allow-Origin", "*");
           res.header("Access-Control-Allow-Headers", "X-Requested-With");
           res.header('Access-Control-Allow-Headers', 'Content-Type');
           next();
    });
    
  • 3

    前段时间,我遇到了这个问题所以我这样做是为了在我的nodejs app中允许CORS:

    首先,使用以下命令 need to install cors

    npm install cors --save
    

    现在 add the following code 到您的应用启动文件,如( app.js or server.js

    var express = require('express');
    var app = express();
    
    var cors = require('cors');
    var bodyParser = require('body-parser');
    
    //enables cors
    app.use(cors({
      'allowedHeaders': ['sessionId', 'Content-Type'],
      'exposedHeaders': ['sessionId'],
      'origin': '*',
      'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
      'preflightContinue': false
    }));
    
    require('./router/index')(app);
    
  • 577

    要回答您的主要问题,如果POST或GET中包含任何非简单内容或 Headers ,则CORS规范仅要求OPTIONS调用在POST或GET之前 .

    需要CORS飞行前请求(OPTIONS调用)的内容类型是除以下内容之外的任何内容类型:

    • application/x-www-form-urlencoded

    • multipart/form-data

    • text/plain

    除上述内容之外的任何其他内容类型都将触发飞行前请求 .

    至于 Headers ,除以下内容之外的任何请求 Headers 都会触发飞行前请求:

    • Accept

    • Accept-Language

    • Content-Language

    • Content-Type

    • DPR

    • Save-Data

    • Viewport-Width

    • Width

    任何其他请求标头将触发飞行前请求 .

    因此,您可以添加自定义标头,例如: x-Trigger: CORS ,这应该触发飞行前请求并点击OPTIONS块 .

    MDN Web API Reference - CORS Preflighted requests

  • 1

    在typescript中,如果你想使用node.js包cors

    /**
    * app.ts
    * If you use the cors library
    */
    
    import * as express from "express";
    [...]
    import * as cors from 'cors';
    
    class App {
       public express: express.Application;
    
       constructor() {
           this.express = express();
           [..]
           this.handleCORSErrors();
       }
    
       private handleCORSErrors(): any {
           const corsOptions: cors.CorsOptions = {
               origin: 'http://example.com',
               optionsSuccessStatus: 200
           };
           this.express.use(cors(corsOptions));
       }
    }
    
    export default new App().express;
    

    如果您不想使用第三方库来进行cors错误处理,则需要更改handleCORSErrors()方法 .

    /**
    * app.ts
    * If you do not use the cors library
    */
    
    import * as express from "express";
    [...]
    
    class App {
       public express: express.Application;
    
       constructor() {
           this.express = express();
           [..]
           this.handleCORSErrors();
       }
    
       private handleCORSErrors(): any {
           this.express.use((req, res, next) => {
               res.header("Access-Control-Allow-Origin", "*");
               res.header(
                   "Access-Control-ALlow-Headers",
                   "Origin, X-Requested-With, Content-Type, Accept, Authorization"
               );
               if (req.method === "OPTIONS") {
                   res.header(
                       "Access-Control-Allow-Methods",
                       "PUT, POST, PATCH, GET, DELETE"
                   );
                   return res.status(200).json({});
               } 
               next(); // send the request to the next middleware
           });
        }
    }
    
    export default new App().express;
    

    使用app.ts文件

    /**
    * server.ts
    */
    import * as http from "http";
    import app from "./app";
    
    const server: http.Server = http.createServer(app);
    
    const PORT: any = process.env.PORT || 3000;
    server.listen(PORT);
    
  • 109

    我已经制作了一个更完整的中间件,适合快递或连接 . 它支持 OPTIONS 预检检查请求 . 请注意,它允许CORS访问任何内容,如果要限制访问,可能需要进行一些检查 .

    app.use(function(req, res, next) {
        var oneof = false;
        if(req.headers.origin) {
            res.header('Access-Control-Allow-Origin', req.headers.origin);
            oneof = true;
        }
        if(req.headers['access-control-request-method']) {
            res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
            oneof = true;
        }
        if(req.headers['access-control-request-headers']) {
            res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
            oneof = true;
        }
        if(oneof) {
            res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
        }
    
        // intercept OPTIONS method
        if (oneof && req.method == 'OPTIONS') {
            res.send(200);
        }
        else {
            next();
        }
    });
    
  • 2

    这对我来说很有用,因为它在路线中很容易实现,我使用meanjs和它的工作正常,safari,chrome等 .

    app.route('/footer-contact-form').post(emailer.sendFooterMail).options(function(req,res,next){ 
            res.header('Access-Control-Allow-Origin', '*'); 
            res.header('Access-Control-Allow-Methods', 'GET, POST');
            res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
            return res.send(200);
    
        });
    
  • 19

    我发现使用npm请求包(https://www.npmjs.com/package/request)非常容易

    然后我将我的解决方案基于这篇文章http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/

    'use strict'
    
    const express = require('express');
    const request = require('request');
    
    let proxyConfig = {
        url : {
            base: 'http://servertoreach.com?id=',
        }
    }
    
    /* setting up and configuring node express server for the application */
    let server = express();
    server.set('port', 3000);
    
    
    /* methods forwarded to the servertoreach proxy  */
    server.use('/somethingElse', function(req, res)
    {
        let url = proxyConfig.url.base + req.query.id;
        req.pipe(request(url)).pipe(res);
    });
    
    
    /* start the server */
    server.listen(server.get('port'), function() {
        console.log('express server with a proxy listening on port ' + server.get('port'));
    });
    
  • 31

    首先只需在项目中安装cors . 将终端(命令提示符)和 cd 带到项目目录并运行以下命令:

    npm install cors --save
    

    然后获取server.js文件并更改代码以在其中添加以下内容:

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

    这对我有用..

  • 0

    安装expressjs的cors模块 . 你可以按照这些步骤>

    Installation

    npm install cors
    

    Simple Usage (Enable All CORS Requests)

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

    欲了解更多详情,请访问https://github.com/expressjs/cors

  • 9

    如果您想使控制器特定,您可以使用:

    res.setHeader('X-Frame-Options', 'ALLOWALL');
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'POST, GET');
    res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    

    请注意,这也将允许iframe .

  • 18

    使用Express 4.2.0(编辑:似乎在4.3.0中不起作用)的最简单的解决方案是:

    function supportCrossOriginScript(req, res, next) {
        res.status(200);
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Content-Type");
    
        // res.header("Access-Control-Allow-Headers", "Origin");
        // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        // res.header("Access-Control-Allow-Methods","POST, OPTIONS");
        // res.header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT, HEAD");
        // res.header("Access-Control-Max-Age","1728000");
        next();
    }
    
    // Support CORS
    app.options('/result', supportCrossOriginScript);
    
    app.post('/result', supportCrossOriginScript, function(req, res) {
        res.send('received');
        // do stuff with req
    });
    

    我想 app.all('/result', ...) 也会起作用......

  • 7

    我发现最简单的方法是使用node.js包cors . 最简单的用法是:

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

    当然,有很多方法可以根据您的需要配置行为;上面链接的页面显示了许多示例 .

  • 1

    我用了以下几个步骤网络应用程序,我取得了成功:

    将cors包添加到express:

    npm install cors --save
    

    添加以下行 after the bodyParser configuration . 我在bodyParser之前添加了一些麻烦:

    // enable cors to the server
    const corsOpt = {
        origin: process.env.CORS_ALLOW_ORIGIN || '*', // this work well to configure origin url in the server
        methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], // to works well with web app, OPTIONS is required
        allowedHeaders: ['Content-Type', 'Authorization'] // allow json and token in the headers
    };
    app.use(cors(corsOpt)); // cors for all the routes of the application
    app.options('*', cors(corsOpt)); // automatic cors gen for HTTP verbs in all routes, This can be redundant but I kept to be sure that will always work.
    
  • 2

    npm install cors --save
    

    只需在您的主文件中添加这些行,您的请求将继续(在任何路由之前保留) .

    const cors = require('cors');
    const express = require('express');
    let app = express();
    app.use(cors());
    app.options('*', cors());
    
  • 0

    保持路由的相同想法 . 我用这个代码:

    app.all('/*', function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "X-Requested-With");
      next();
    });
    

    http://enable-cors.org/server_expressjs.html示例类似

相关问题