第五章 跨域资源共享(CORS):现代Web开发中的关键机制

简介: 第五章 跨域资源共享(CORS):现代Web开发中的关键机制

引言

在现代Web开发中,不同源之间数据交换的需求日益增长。然而,出于安全原因,浏览器对从一个域向另一个域发起请求有着严格的限制,这就是同源策略(Same-Origin Policy)。


然而,同源策略限制了后端访问接口必须与网站一致!这就非常不灵活,尤其现在web应用多为多端应用,又同时需要多个地址的服务的情况下。(这里是重点)

为了解决这一问题,并实现安全、灵活的跨域通信,跨域资源共享(Cross-Origin Resource Sharing, 简称CORS)应运而生。本文将深入探讨CORS的工作原理、配置方法及其在实际应用中的重要性。

一、同源策略与跨域限制

1. 概念

同源策略(Same-Origin Policy)是浏览器为保护用户信息安全而实施的一种安全机制。在Web开发领域,同源策略规定了来自同一来源的文档或脚本可以相互读取和交互数据,而不同源则不能直接进行这样的操作。这里的“源”由协议、域名和端口三部分组成,如果这三者完全相同,则认为两个资源是同源的。

2. 举例说明

  1. 同源示例
  • 这两个URL具有相同的协议(HTTPS)、相同的域名(www.example.com)和相同的端口(默认HTTP/HTTPS端口,即443),因此它们被认为是同源的,这个请求将被允许执行。
  1. 非同源示例
  • 当前网页地址为 https://www.example.com/index.html。
  • 页面尝试发送一个AJAX请求到 http://api.other-example.com/data
  • 这两个URL的协议不同(一个是HTTPS,另一个是HTTP),或者域名不同(www.example.com与api.other-example.com),因此它们被视为不同源。
  • 根据同源策略,浏览器将会阻止此跨域请求,除非服务器配置了支持跨域资源共享(CORS)并明确允许从www.example.com发起请求。

同源策略旨在防止恶意网站通过JavaScript读取其他站点的敏感信息,例如cookies或其他存储在本地的数据。对于需要进行跨域通信的应用场景,可以通过CORS、JSONP等技术实现安全可控的数据交换。

二、跨域资源共享(CORS)

1. 概念

首先要明确的是CORS是一种W3C标准(非常重要,是浏览器和服务器共同去完成的一套http请求机制),允许服务器明确声明哪些外部域可以访问其资源。通过CORS,服务器能够设置允许哪些HTTP请求方法、头信息和自定义响应头被其他域使用。


跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种允许网页从不同源(domain、协议或端口不一致)获取资源的机制。在Web开发中,由于浏览器的安全策略——同源策略(Same-Origin Policy),一个源下的文档或脚本默认情况下不能访问另一个源的资源。然而,在实际应用中,往往需要跨域请求以实现数据共享和服务调用。

2. CORS工作原理与举例说明

1. CORS请求类型

  • 简单请求:对于GET、POST等简单HTTP方法以及某些标准头部字段的请求,可以被视为简单请求。浏览器会自动在请求头中添加Origin字段,标识请求发起者的源。

示例:

GET /data HTTP/1.1
Host: api.example.com
Origin: https://www.example.net

服务器收到请求后,会在响应头中返回Access-Control-Allow-Origin来指定哪些源可以访问该资源。

2. 预检请求(Preflight Request)

对于非简单请求,如使用自定义头部字段或PUT、DELETE等其他HTTP方法的请求,浏览器会先发送一个OPTIONS预检请求询问服务器是否接受该跨域请求。

示例:

OPTIONS /data HTTP/1.1
Host: api.example.com
Origin: https://www.example.net
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

-- Response --
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.net
Access-Control-Allow-Methods: PUT, POST, DELETE
Access-Control-Allow-Headers: X-Custom-Header

3. 服务器配置

服务器根据接收到的请求和自身的CORS策略,通过设置特定的响应头信息来决定是否允许这次跨域请求。

例如,服务器可以通过设置如下响应头允许来自https://www.example.net的请求:

Access-Control-Allow-Origin: https://www.example.net


4. CORS安全控制

CORS还提供了其他一些响应头用于更精细的权限控制,如:

  • Access-Control-Allow-Credentials 控制是否允许携带凭据(如 Cookies 或 HTTP 认证信息)进行跨域请求。
  • Access-Control-Max-Age 设置预检请求结果的有效期,减少重复预检次数。

三、CORS请求类型与流程

1. 简单请求

  • 对于GET、POST等简单HTTP方法以及一些特定的头部字段,浏览器可以直接发起跨域请求,无需预检。

浏览器会在请求头中自动添加Origin字段表明来源域,服务器根据此信息决定是否放行请求。

在浏览器发起跨域请求时,对于非简单请求(如包含了自定义头部、PUT、DELETE等方法的请求)和所有预检请求(OPTIONS),

  • 浏览器会自动在请求头中添加一个Origin字段。这个字段包含的是当前发出请求的页面所在的源信息,即协议+域名+端口。

如果一个网页加载自 https://example.com,当它尝试向 https://api.example.net 发送一个跨域请求时,浏览器会在请求头中插入如下内容:

Origin: https://example.com

服务器收到请求后,可以通过检查Origin头来判断请求是否来自允许访问的源。如果服务器配置了CORS策略,并且Access-Control-Allow-Origin响应头中包含了与请求头中的Origin相匹配的源,那么该请求将被放行;否则,请求会被服务器拒绝。

举个例子,服务器可以这样设置其CORS策略以允许来自https://example.com的请求:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com

2. 预检请求(Preflight Request)

  • 当请求方法不是简单的GET/POST或者包含自定义头部时,浏览器会先发送一个OPTIONS方法的预检请求来询问服务器。
  • 服务器收到预检请求后,若返回的响应头中包含了Access-Control-Allow-OriginAccess-Control-Allow-Methods等相关字段并允许当前源,则后续的实际请求会被正常处理。

预检请求(Preflight Request)是CORS机制中的一种特殊请求,用于非简单请求(例如使用了自定义头部字段、PUT、DELETE等方法的请求)在实际发送前向服务器询问是否允许该跨域请求。以下是一个关于预检请求的例子,包括客户端发起请求和服务器端响应:

3. 客户端JavaScript示例

// 使用fetch API 发起一个带有自定义头部的PUT请求
fetch('https://api.example.com/data', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'X-Custom-Header': 'custom-value'
  },
  body: JSON.stringify({ key: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

在此例中,由于我们设置了自定义头部X-Custom-Header并使用了PUT方法,浏览器会先发送一个OPTIONS预检请求。

4. 服务器端响应示例(以Node.js + Express为例)

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

app.options('/data', (req, res) => { // 处理预检请求
  res.set({
    'Access-Control-Allow-Origin': 'https://www.example.net', // 允许特定源
    'Access-Control-Allow-Methods': 'PUT, POST, DELETE, OPTIONS', // 允许的方法列表
    'Access-Control-Allow-Headers': 'Content-Type, X-Custom-Header', // 允许的头部
    'Access-Control-Max-Age': 86400 // 预检结果缓存时间(单位秒)
  });

  if (req.headers.origin) {
    res.setHeader('Access-Control-Allow-Credentials', true); // 允许携带凭据(如 Cookies)
  }

  res.status(204).send(); // 预检请求不需要返回数据体,仅需设置正确的响应头
});

app.put('/data', (req, res) => {
  // 实际处理PUT请求逻辑
});

// ...其他路由...

app.listen(3000, () => console.log('Server started on port 3000'));

当客户端发起上述跨域PUT请求时,浏览器首先发送一个OPTIONS预检请求到服务器。如果服务器的预检响应表明允许该请求,则浏览器才会继续发送实际的PUT请求。

四、CORS响应头详解

  • Access-Control-Allow-Origin: 必需字段,指定允许接收请求的源。
  • Access-Control-Allow-Methods: 指定允许的方法列表,如GET, POST, PUT, DELETE等。
  • Access-Control-Allow-Headers: 允许客户端发送的非标准请求头。
  • Access-Control-Allow-Credentials: 表示是否允许携带cookie和认证信息进行跨域请求。
  • Access-Control-Max-Age: 设置预检请求结果的有效期,减少重复预检的次数。

五、CORS配置实例

在服务器端(如Node.js的Express框架),可以通过中间件实现CORS:

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

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有源
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); // 允许的方法
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 允许的头部
  if (req.method === 'OPTIONS') {
    res.send(204); // 预检请求则直接返回204状态码
  } else {
    next(); // 其他请求继续执行路由处理函数
  }
});

// ... 添加你的路由逻辑 ...

六、CORS实践与安全性考量

尽管CORS极大地增强了Web应用程序的功能性和灵活性,但它也引入了一些潜在的安全风险,比如可能泄露敏感信息。因此,在实施CORS策略时务必谨慎,避免过于宽松的设置,如只允许特定可信的源访问资源,同时对允许的方法和头部进行严格控制。


总结来说,跨域资源共享作为现代Web开发的重要组成部分,对于构建高效、安全且具有丰富交互体验的应用至关重要。理解并正确配置CORS不仅能解决开发过程中的常见跨域问题,还能有效提升系统的安全性。


衷心感谢您阅读至此,若您在本文中有所收获,恳请您不吝点赞、评论或分享,您的支持是我们持续创作高质量内容的动力源泉。同时,也诚挚邀请您关注本博客,以便获取更多前端开发与设计相关的深度解析和实战技巧,我们期待与您共同成长,一起探索前端世界的无限精彩!

相关文章
|
4月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
400 4
|
4月前
|
安全 API PHP
PHP中实现CORS跨域资源共享的方法
通过这种方式,你可以在PHP应用中灵活地实现CORS,以支持跨域Web应用的需求。
313 15
|
8月前
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
8月前
|
JavaScript 前端开发 API
鸿蒙5开发宝藏案例分享---Web加载时延优化解析
本文深入解析了鸿蒙开发中Web加载完成时延的优化技巧,结合官方案例与实际代码,助你提升性能。核心内容包括:使用DevEco Profiler和DevTools定位瓶颈、四大优化方向(资源合并、接口预取、图片懒加载、任务拆解)及高频手段总结。同时提供性能优化黄金准则,如首屏资源控制在300KB内、关键接口响应≤200ms等,帮助开发者实现丝般流畅体验。
|
前端开发 JavaScript Shell
鸿蒙5开发宝藏案例分享---Web页面内点击响应时延分析
本文为鸿蒙开发者整理了Web性能优化的实战案例解析,结合官方文档深度扩展。内容涵盖点击响应时延核心指标(≤100ms)、性能分析工具链(如DevTools时间线、ArkUI Trace抓取)以及高频优化场景,包括递归函数优化、网络请求阻塞解决方案和setTimeout滥用问题等。同时提供进阶技巧,如首帧加速、透明动画陷阱规避及Web组件初始化加速,并通过优化前后Trace对比展示成果。最后总结了快速定位问题的方法与开发建议,助力开发者提升Web应用性能。
|
8月前
|
JSON 开发框架 自然语言处理
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)
本文主要介绍了应用开发中的三大核心内容:生命周期管理、资源限定与访问以及多语言支持。在生命周期部分,详细说明了应用和页面的生命周期函数及其触发时机,帮助开发者更好地掌控应用状态变化。资源限定与访问章节,则聚焦于资源限定词的定义、命名规则及匹配逻辑,并阐述了如何通过 `$r` 引用 JS 模块内的资源。最后,多语言支持部分讲解了如何通过 JSON 文件定义多语言资源,使用 `$t` 和 `$tc` 方法实现简单格式化与单复数格式化,为全球化应用提供便利。
312 104
|
8月前
|
JavaScript 前端开发 API
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(二)
本文介绍了HarmonyOS应用开发中的HML、CSS和JS语法。HML作为标记语言,支持数据绑定、事件处理、列表渲染等功能;CSS用于样式定义,涵盖尺寸单位、样式导入、选择器及伪类等特性;JS实现业务逻辑,包括ES6语法支持、对象属性、数据方法及事件处理。通过具体代码示例,详细解析了页面构建与交互的实现方式,为开发者提供全面的技术指导。
310 104
|
8月前
|
开发框架 编解码 JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(一)
该文档详细介绍了一个兼容JS的类Web开发范式的方舟开发框架,涵盖概述、文件组织、js标签配置及app.js等内容。框架采用HML、CSS、JavaScript三段式开发方式,支持单向数据绑定,适合中小型应用开发。文件组织部分说明了目录结构、访问规则和媒体文件格式;js标签配置包括实例名称、页面路由和窗口样式信息;app.js则描述了应用生命周期与对象管理。整体内容旨在帮助开发者快速构建基于方舟框架的应用程序。
324 102
|
11月前
|
关系型数据库 MySQL 数据库
基于Flink CDC 开发,支持Web-UI的实时KingBase 连接器,三大模式无缝切换,效率翻倍!
TIS 是一款基于Web-UI的开源大数据集成工具,通过与人大金仓Kingbase的深度整合,提供高效、灵活的实时数据集成方案。它支持增量数据监听和实时写入,兼容MySQL、PostgreSQL和Oracle模式,无需编写复杂脚本,操作简单直观,特别适合非专业开发人员使用。TIS率先实现了Kingbase CDC连接器的整合,成为业界首个开箱即用的Kingbase CDC数据同步解决方案,助力企业数字化转型。
2428 5
基于Flink CDC 开发,支持Web-UI的实时KingBase 连接器,三大模式无缝切换,效率翻倍!
|
9月前
|
Web App开发 前端开发 JavaScript
鸿蒙5开发宝藏案例分享---Web适配一多开发实践
这是一份实用的鸿蒙Web多设备适配开发指南,针对开发者在不同屏幕尺寸下的布局难题提供了解决方案。文章通过三大法宝(相对单位、媒体查询和窗口监听)详细介绍如何实现智能适配,并提供了多个实战案例,如宫格布局、对话框变形和自适应轮播图等。此外,还分享了调试技巧及工具推荐,帮助开发者快速上手并优化性能。最后鼓励读者实践探索,并提示更多官方资源等待发现。