什么是跨域?
在浏览器中,当一个网站试图请求另一个网站的资源时,如果两个网站的域名、协议或端口不同,就会发生跨域问题。例如,一个网站能够从 https://www.example.com
请求 https://api.example.com
,但不能从 https://www.example.com
请求 https://api.example.org
。
跨域问题是因为浏览器的同源策略所致。同源策略是一种浏览器安全机制,它限制了一个网页可以访问另一个网页的能力。同源策略要求网页只能与同一域名、协议和端口的网页进行通信。
什么是 CORS?
跨域资源共享(CORS)是一种通过在 HTTP 头中添加特定信息的方法,允许浏览器向其他域请求服务的机制。CORS 标准描述了一个浏览器和服务器之间的安全、授权和通信机制,允许 Web 应用程序从不同的域中访问其资源。
CORS 机制中使用了两种类型的 HTTP 请求:简单请求和非简单请求。下面将对这两种请求进行介绍。
简单请求
如果请求满足以下条件,则称之为简单请求:
- 使用 GET、HEAD 或 POST 方法之一;
- 只使用以下的头文件:Accept、Accept-Language、Content-Language、Content-Type(仅限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain);
- Content-Type 的值为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 之一。
对于简单请求,服务器会在响应头中添加一个 Access-Control-Allow-Origin
字段,该字段的值为请求来源的域名,表示允许该域名访问服务器的资源。
非简单请求
如果请求不满足上述条件,则称之为非简单请求。对于非简单请求,浏览器会先发起一个预检请求(Preflight Request)。
预检请求是一种 OPTIONS 请求,用于请求服务器允许跨域请求的白名单信息。预检请求将会包含一个 Origin
头,表示请求来源的域名。服务器需要在响应头中添加以下字段,表示允许请求来源进行跨域请求:
Access-Control-Allow-Origin
:表示允许的请求来源,即允许哪些域名进行跨域请求;Access-Control-Allow-Methods
:表示允许的请求方法,即允许哪些请求方法进行跨域请求;Access-Control-Allow-Headers
:表示允许的请求头,即允许哪些请求头进行跨域请求;Access-Control-Allow-Credentials
:表示允许发送 Cookie 信息,即是否允许在请求中携带 Cookie;Access-Control-Max-Age
:表示预检请求的有效期,即预检请求发送后多久再次发送预检请求。
Hapi 框架的 CORS 支持
Hapi 是一个现代化的 Node.js Web 应用程序框架,它提供了丰富的插件和特性,允许您快速构建高度可测试和可扩展的 Web 应用程序。Hapi 框架通过插件支持 CORS 跨域请求。
Hapi 的官方插件 hapi-cors
可以轻松地实现 CORS 跨域请求,它支持以下功能:
- 跨域请求白名单;
- 允许所有跨域请求;
- 不允许任何跨域请求;
- 自定义 CORS 响应报头;
- 自定义跨域验证函数;
- 支持针对预检请求设置缓存时间。
下面我们来演示如何在 Hapi 中使用 hapi-cors
插件来实现 CORS 跨域请求。
第一步:安装 hapi-cors
插件
使用以下命令安装 hapi-cors
插件:
npm install hapi-cors
第二步:引入 hapi-cors
在 Hapi 服务器中使用以下语句引入 hapi-cors
:
const Hapi = require('@hapi/hapi'); const HapiCors = require('hapi-cors'); const server = Hapi.server({ port: 3000, host: 'localhost' });
第三步:注册 hapi-cors
插件
使用以下语句注册 hapi-cors
插件:
await server.register(HapiCors);
第四步:使用 hapi-cors
插件
使用以下代码启用 hapi-cors
插件:
// javascriptcn.com 代码示例 server.route({ method: 'GET', path: '/', handler: function (request, h) { return 'Hello World!'; }, options: { cors: true } });
示例代码
下面是一个完整的示例代码,演示如何在 Hapi 中使用 hapi-cors
插件实现 CORS 跨域请求:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const HapiCors = require('hapi-cors'); const init = async () => { const server = Hapi.server({ port: 3000, host: 'localhost' }); await server.register(HapiCors); server.route({ method: 'GET', path: '/', handler: function (request, h) { return 'Hello World!'; }, options: { cors: true } }); await server.start(); console.log('Server running on %s', server.info.uri); }; process.on('unhandledRejection', (err) => { console.log(err); process.exit(1); }); init();
总结
CORS 跨域请求是 Web 开发中常见的问题,也是比较复杂的问题。在 Hapi 框架中,可以使用 hapi-cors
插件来实现快速简单地支持 CORS 跨域请求。在使用 hapi-cors
插件时,需要注意一些细节,比如使用哪些配置选项、如何配置 CORS 白名单等,才能确保正确地处理跨域请求。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/651ee4d995b1f8cacd68fd58