app用http3与服务器_用 Node.js 处理 CORS

作者:前端小混混 来源:前端先锋

在本文中,我们将研究怎样用 Express 配置 CORS 以及根据需要定制 CORS 中间件。

4deec7ef013b49d0a9ebb4e47ac2fcae.png

什么是CORS

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

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

假设你当前使用的是 http://example.com/page1,并且你引用的是来自 http://image.com/myimage.jpg 的图片,那么除非 http://image.com 允许与 http://example.com 进行跨域共享,否则将无法获取该图像。

每个 HTTP 请求头中都有一个名为 origin 的头。它定义了域请求的来源。可以用这个头的信息来限制引用你服务器上的资源。

默认来自任何其他来源的请求都会受到浏览器的限制。

例如当开发时如果用的是 React 或 Vue 这类的前端库,则前端应用将运行在 http://localhost:3000 上,同时,你的 Express 服务器可能正在其他端口上运行,例如 http://localhost:2020。这时就需要在这些服务器之间允许 CORS。

如果你在浏览器控制台中看到下图这类的错误。问题可能出在 CORS 限制上:

43223379b2bc73c5093c97382eea4154.png

chrome cors

如果我们需要提供公共 API 并希望控制对某些资源的访问和使用方式时,CORS 能够发挥很大的作用。

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

用 Express 配置 CORS

首先创建一个新的项目,并创建目录结构,然后使用默认设置运行 npm init:

$ mkdir myapp $ cd myapp $ npm init -y 

接下来安装所需的模块。我们将使用 express 和 cors 中间件:

$ 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 消息:

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'); }); 

访问 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/name 或 http://localhost:2020/img/cat.png,则此请求将会被浏览器阻止:

{     message: 'Hello World' } 

如果在其他 Web 应用中运行代码,应该看到以下错误:

2e741f165ead202570677a2792a7d9da.png

控制台错误

1. 用选项配置CORS

还可以用自定义选项来配置 CORS。可以根据需要配置允许的 HTTP 方法,例如 GET 和 POST。

下面是通过 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.com 或 http://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)); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园的建设目标是通过数据整合、全面共享,实现校园内教学、科研、管理、服务流程的数字化、信息化、智能化和多媒体化,以提高资源利用率和管理效率,确保校园安全。 智慧校园的建设思路包括构建统一支撑平台、建立完善管理体系、大数据辅助决策和建设校园智慧环境。通过云架构的数据中心与智慧的学习、办公环境,实现日常教学活动、资源建设情况、学业水平情况的全面统计和分析,为决策提供辅助。此外,智慧校园还涵盖了多媒体教学、智慧录播、电子图书馆、VR教室等多种教学模式,以及校园网络、智慧班牌、校园广播等教务管理功能,旨在提升教学品质和管理水平。 智慧校园的详细方案设计进一步细化了教学、教务、安防和运维等多个方面的应用。例如,在智慧教学领域,通过多媒体教学、智慧录播、电子图书馆等技术,实现教学资源的共享和教学模式的创新。在智慧教务方面,校园网络、考场监控、智慧班牌等系统为校园管理提供了便捷和高效。智慧安防系统包括视频监控、一键报警、阳光厨房等,确保校园安全。智慧运维则通过综合管理平台、设备管理、能效管理和资产管理,实现校园设施的智能化管理。 智慧校园的优势和价值体现在个性化互动的智慧教学、协同高效的校园管理、无处不在的校园学习、全面感知的校园环境和轻松便捷的校园生活等方面。通过智慧校园的建设,可以促进教育资源的均衡化,提高教育质量和管理效率,同时保障校园安全和提升师生的学习体验。 总之,智慧校园解决方案通过整合现代信息技术,如云计算、大数据、物联网和人工智能,为教育行业带来了革命性的变革。它不仅提高了教育的质量和效率,还为师生创造了一个更加安全、便捷和富有智慧的学习与生活环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值