热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

详解使用Node.js怎么处理CORS

在本文中,我们将研究怎样用Express配置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.js 的文件,用来充当 Web 服务器,并实现几个请求处理函数:

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 上的网页可以将我们的域用作图像的来源:

为单个路由启用 CORS

如果只需要其中某一个路由,可以在某个路由中将 cors 配置为中间件:

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

这会允许任何域访问特定的路由。在当前的情况下,其他域都只能访问 / 路由。仅在与 API(在本例中为http://localhost:2020)的相同域中发起的请求才能访问 /:name 路由。

如果尝试另一个来源发送请求到 / 路径将会成功,并且会收到 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:8080 发送到 http://localhost:2020

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

//
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 // 对于旧版浏览器的支持
    methods: "GET, PUT"
}

app.use(cors(corsOptions));

如果从 http://localhost:8080 发送POST请求,则浏览器将会阻止它,因为仅支持 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。

例如假设要允许 http://something.com 和 http://example.com 对 .jpg 文件进行CORS共享:

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) {
        // 为此请求启用 CORS
        corsOptiOns= { origin: true }
    } else {
        // 为此请求禁用 CORS
        corsOptiOns= { origin: false }
    }
    callback(null, corsOptions)
}

app.use(cors(corsOptionsDelegate));

回调函数接受两个参数,第一个是传递 null 的错误,第二个是传递 { origin: false } 的选项。第二个参数可以是用 Express 的 request 对象构造的更多选项。

所以 http://something.comhttp://example.com 上的 Web 应用将能够按照自定义配置从服务器引用扩展名为 .jpg 的图片。

这样可以成功引用资源文件:

但是下面的文件将会被阻止:

从数据源加载允许的来源列表作

还可以用保存在数据库中的白名单列表或任何一种数据源来允许 CORS:

var corsOptiOns= {
    origin: function (origin, callback) {
        // 从数据库加载允许的来源列表
        // 例如:origins = ['http://example.com', 'http//something.com']
        database.loadOrigins((error, origins) => {
            callback(error, origins);
        });
    }
}

app.use(cors(corsOptions));

原文:https://stackabuse.com/handling-cors-with-node-js/

作者:Janith Kasun

更多编程相关知识,可访问:编程教学!!

以上就是详解使用Node.js怎么处理CORS的详细内容,更多请关注 第一PHP社区 其它相关文章!


推荐阅读
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 必须先赞下国人npm库作品:node-images(https:github.comzhangyuanweinode-images),封装了跨平台的C++逻辑,形成nodejsAP ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • 微信民众号商城/小顺序商城开源项目介绍及使用教程
    本文介绍了一个基于WeiPHP5.0开发的微信民众号商城/小顺序商城的开源项目,包括前端和后端的目录结构,以及所使用的技术栈。同时提供了项目的运行和打包方法,并分享了一些调试和开发经验。最后还附上了在线预览和GitHub商城源码的链接,以及加入前端交流QQ群的方式。 ... [详细]
  • React 小白初入门
    推荐学习:React官方文档:https:react.docschina.orgReact菜鸟教程:https:www.runoob.c ... [详细]
  • vuecli创建项目(详情步骤)
    1、安装node环境2、下载vue和vue-cli脚手架命令行输入npm ... [详细]
  • RN即ReactNative基于React框架针对移动端的跨平台框架,在学习RN前建议最好熟悉下html,css,js,当然如果比较急,那就直接上手吧,毕竟用学习前面基础的时间,R ... [详细]
  • 这篇文章给大家介绍怎么从源码启动和编译IoTSharp ,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。IoTSharp项目是 ... [详细]
  • 前言:原本纠结于Web 模板,选了Handlebars。后来发现页面都是弱逻辑的,不支持复杂逻辑表达式。几乎要放弃之际,想起了Javascript中eval函数。虽然eval函 ... [详细]
  • JavaScript和Python是用于构建各种应用程序的两种有影响力的编程语言。尽管JavaScript多年来一直是占主导地位的编程语言,但Python的迅猛发展有 ... [详细]
  • Node.js详细安装及环境配置
    1、下载安装根据自己电脑系统及位数选择,我这里选择windows64位.msi格式安装包(官网:https:odejs.orgzh-cndownload).msi和.zip格式区别 ... [详细]
  • 这么多流媒体服务器?你怎么技术选型?
    在上一篇文章里我们介绍了我们介绍了MCU和SFU的优缺点,webRTC通信方案SFU和MCU的区别?下面就来探讨下常见的SFU开源解决方案,当然,你也可以自己实现SFU流媒体服务器 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
author-avatar
醇情咖啡_799
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有