美文网首页
使用Node.js处理CORS

使用Node.js处理CORS

作者: 魂斗驴 | 来源:发表于2021-04-28 09:16 被阅读0次

介绍

在本文中,我们将研究什么是CORS,如何使用Express配置CORS,以及如何根据需要定制CORS中间件。

什么是CORS

CORS跨域资源共享的简写。它是一种机制,允许或限制Web服务器上请求的资源,具体取决于启动HTTP请求的位置。

此策略用于保护特定Web服务器免受其他网站或域的访问。例如,只有允许的域才能访问服务器中的托管文件,例如样式表,图像或脚本。

如果您当前正在使用http://example.com/page1并且要从中引用图像http://image.com/myimage.jpg,则除非http://image.com允许使用进行跨域共享,否则http://example.com将无法获取该图像。

origin每个HTTP请求中都有一个HTTP标头。它定义了域请求的来源。我们可以使用标头信息来限制或允许来自Web服务器的资源来保护它们。

默认情况下,来自任何其他来源的请求都将受到浏览器的限制。

例如,当您仍处于开发阶段时-如果您使用的是诸如React之类的前端库,则将在上使用您的前端应用程序http://localhost:3000。同时,您的Express服务器可能正在其他端口上运行,例如http://localhost:2020

因此,您需要在这些服务器之间允许CORS。

如果您在浏览器控制台中看到此常见错误。CORS限制可能是问题所在:

当您提供公共API并希望控制对某些资源的访问以及人们的使用方式时,CORS确实很有用。

另外,如果您想在其他网页上使用自己的API或文件,则可以简单地将CORS配置为允许这样做,同时仍将其他人拒之门外。

使用Express配置CORS

让我们从一个新的项目开始。我们将为其创建一个目录,输入目录并npm init使用默认设置运行:

$ mkdir myapp
$ cd myapp
$ npm init -y

然后,让我们安装所需的模块。我们将使用expresscors中间件:

$ npm i --save express
$ npm i --save cors

然后,让我们开始创建一个具有两个路由的快速Web应用程序,以演示CORS的工作原理。

我们将创建一个称为index.jsWeb服务器的文件,其中包含几个请求处理程序:

const express = require('express');
const cors = require('cors');

const app = express();

app.get('/', (req, res) => {
    res.json({
        message: 'Hello World'
    });
});

app.get('/:name', (req, res) => {
    let name = req.params.name;

    res.json({
        message: `Hello ${name}`
    });
});

app.listen(2020, () => {
    console.log('server is listening on port 2020');
});

让我们运行应用程序和服务器:

$ node index.js

现在,如果您转到http://localhost:2020/-服务器应返回JSON消息:

{
  "message": "Hello World"
}

另外,如果您http://localhost:2020/something应该会看到:

{
  "message": "Hello something"
}

启用所有CORS请求

如果要为所有请求启用CORS,则只需cors在配置路由之前使用中间件即可:

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors())

......

如果需要,这将允许所有路由都可以在网络上的任何位置访问。因此,在我们的示例中,每个域都可以访问这两个路由。

例如,如果我们的服务器正在运行http://www.example.com并提供诸如图像之类的内容,则我们允许其他域http://www.differentdomain.com引用诸如http://www.example.com中的内容。

因此,上的网页http://www.differentdomain.com可以将我们的域用作图像的来源:

<img src="http://www.example.com/img/cat.jpg">

为单个路由启用CORS

但是,如果您需要某个路由而不是其他路由,则可以cors在某个路由中将其配置为中间件,而不是将其配置为整个应用程序:

app.get('/', cors(), (req, res) => {
    res.json({
        message: 'Hello World'
    });
});

这将允许任何域都可以访问特定路由。因此,在您的情况下,/每个域都只能访问该路由。/:name只有在与API相同的域中发起的请求(http://localhost:2020在我们的示例中)才可以访问该路由。

例如,如果您尝试将获取请求/从其他来源发送到路径-它将成功,并且您将获得Hello World消息作为响应:

fetch('http://localhost:2020/')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(err => console.error(err));

如果运行以下代码,您应该看到来自服务器的响应已成功登录到控制台:

{
    message: 'Hello World'
}

但是,如果您尝试访问除根路径之外的其他任何路径,例如http://localhost:2020/namehttp://localhost:2020/img/cat.png,则此请求将被浏览器阻止:

fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

如果您尝试在其他Web应用程序中运行此代码,则应该看到以下错误:

使用选项配置CORS

您还可以将配置选项与CORS结合使用以进一步自定义此选项。您可以使用配置来允许单个域或子域访问,可以配置允许的HTTP方法,例如GETPOST根据您的要求。

您可以通过以下方式使用CORS选项允许单个域访问:

var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));

如果您在源中配置域名-服务器将允许来自已配置域的CORS。因此,http://localhost:8080在我们的情况下,将可以访问该API ,并禁止其他域使用。

如果我们发送GET请求,则访问任何路径都应该可行,因为这些选项是在应用程序级别而不是功能级别应用的。

因此,如果我们运行以下代码并从发送请求http://localhost:8080http://localhost:2020

fetch('http://localhost:2020/')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// Or

fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

我们被允许从该应用程序和域中获取信息。

您还可以根据需要配置允许的HTTP方法:

var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
    methods: "GET, PUT"
}

app.use(cors(corsOptions));

如果我们POST从发送请求http://localhost:8080,则该请求只会被浏览器阻止,GET并且PUT受支持:

fetch('http://localhost:2020', {
  method: 'POST',
  body: JSON.stringify({name: "janith"}),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));

使用功能配置动态CORS起源

如果配置不满足您的要求,则可以创建功能来定制CORS。

例如,假设您要允许CORS共享.jpg文件http://something.comhttp://example.com

const allowlist = ['http://something.com', 'http://example.com'];

    const corsOptionsDelegate = (req, callback) => {
    let corsOptions;

    let isDomainAllowed = whitelist.indexOf(req.header('Origin')) !== -1;
    let isExtensionAllowed = req.path.endsWith('.jpg');

    if (isDomainAllowed && isExtensionAllowed) {
        // Enable CORS for this request
        corsOptions = { origin: true }
    } else {
        // Disable CORS for this request
        corsOptions = { origin: false }
    }
    callback(null, corsOptions)
}

app.use(cors(corsOptionsDelegate));

回调函数将接受两个参数。第一个是我们通过的错误,null第二个是我们通过的选项{ origin: false }。第二个参数可能是使用requestExpress请求处理程序中的对象构造的许多选项。

因此,在自定义功能中配置的,托管在Web应用程序上http://something.comhttp://example.com能够.jpg从服务器引用带有扩展名的图像的Web应用程序。

因此,以下任何一个都将成功完成以下图像附件:

<img src="http://yourdomain.com/img/cat.jpg">

但是以下附件将被阻止:

<img src="http://yourdomain.com/img/cat.png">

从数据源加载允许的来源清单

您还可以使用数据库中允许的域的列表或使用任何后备数据源来允许CORS:

var corsOptions = {
    origin: function (origin, callback) {
        // Loading a list of allowed origins from the database
        // Ex.. origins = ['http://example.com', 'http//something.com']
        database.loadOrigins((error, origins) => {
            callback(error, origins);
        });
    }
}

app.use(cors(corsOptions));

结论

在本文中,我们介绍了CORS是什么以及如何使用Express对其进行配置。然后,我们为所有请求,特定请求,添加的选项和限制设置了CORS,并为动态CORS配置定义了自定义功能。

参考

Handling CORS with Node.js

相关文章

  • 使用Node.js处理CORS

    介绍 在本文中,我们将研究什么是CORS,如何使用Express配置CORS,以及如何根据需要定制CORS中间件。...

  • AJAX 跨域请求常用两种处理方法

    AJAX 跨域请求常用两种处理方法 -- 第一、 使用 跨域资源共享(CORS) CORS(Cross-Origi...

  • CORS on ExpressJS

    CORS on ExpressJS In your ExpressJS app on node.js, do th...

  • CORS 跨域 Cookie

    前言:在之前的文章中我已经对如何使用 CORS 处理跨域请求进行了介绍,在本文中,我将介绍如何在 CORS 跨域的...

  • CORS 跨域 Cookie 的设置与获取

    前言:在之前的文章中我已经对如何使用 CORS 处理跨域请求进行了介绍,在本文中,我将介绍如何在 CORS 跨域的...

  • Node.js多进程

    Node.js多进程Node.js单线程模式运行的,使用事件处理并发。 exec() 使用子进程的执行命令,缓存子...

  • express 解决跨域

    使用cors中间件解决跨域问题 npm install cors 安装中间件 const cors = requ...

  • 跨域解决方案

    使用cors库 如下 如下

  • flask 中实现跨域请求

    pip install flask-cors可以安装flask-cors库,用来处理flask中跨域请求。 当我们...

  • express解决跨域问题

    有以下2种解决办法: 第一种,使用cors插件 先安装cors插件 npm install cors --save...

网友评论

      本文标题:使用Node.js处理CORS

      本文链接:https://www.haomeiwen.com/subject/vqtvlltx.html