HTTP 第六章 跨资源共享(CORS)

这篇具有很好参考价值的文章主要介绍了HTTP 第六章 跨资源共享(CORS)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

跨资源共享(CORS)

跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。

例如:运行在 https://baidu.com 的js代码使用 XMLHttpRequest 向 https://google.com 发起请求。

出于安全性,浏览器限制脚本内发起的跨源 HTTP 请求。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。

HTTP 第六章 跨资源共享(CORS),网络通信,http,网络协议,网络

CORS 机制允许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以安全进行。

CORS 规范要求

对可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。

服务器确认允许之后,才发起实际的 HTTP 请求。

在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(例如 Cookie 和 HTTP 认证相关数据)

跨域请求的分类

简单请求

简单请求不会触发 CORS 预检请求。

如果请求满足所有下述条件,则该请求可视为简单请求:

  • 请求方法是以下三种方法之一:
    • HEAD
    • GET
    • POST
  • 除了被用户代理自动设置的标头字段(例如 Connection、User-Agent 或其他在 Fetch 规范中定义为禁用标头名称的标头),允许人为设置的字段为 Fetch 规范定义的对 CORS 安全的标头字段集合。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type 所制定的请求头仅限于下列三者
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain
    • Range (只允许简单的范围标头值 如 bytes=256- 或 bytes=127-255)
    • 如果请求是使用 XMLHttpRequest 对象发出的,在返回的 XMLHttpRequest.upload 对象属性上没有注册任何事件监听器;也就是说,给定一个 XMLHttpRequest 实例 xhr,没有调用 xhr.upload.addEventListener(),以监听该上传请求。
    • 请求中没有使用 ReadableStream 对象

例如: 站点 https://foo.example 网页应用想要访问 https://bar.other 的资源

fetch('https://bar.other/test', {
    method: 'GET',
})
    .then(res => res.json())
    .then(res => console.log(res));

此操作实行了客户端和服务器之间的简单交换,使用 CORS 标头字段来处理权限:

HTTP 第六章 跨资源共享(CORS),网络通信,http,网络协议,网络

服务端返回的 Access-Control-Allow-Origin 标头的 Access-Control-Allow-Origin: * 值表明,该资源可以被任意外源访问

const express = require('express');

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.get('/test', (req, res) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.send({
        code: 0,
        data: 'hello world'
    });
});


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

如果 https://bar.other 的资源持有者想限制他的资源只能通过 https://foo.example 来访问,可以这样做:Access-Control-Allow-Origin: https://foo.example

预检请求

当不满足简单请求的条件时,浏览器会发送预检请求“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
"预检请求“ 的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

如下是一个需要执行预检请求的 HTTP 请求:

fetch('https://bar.other/test', {
    method: 'POST',
    headers: {
        'X-PINGOTHER': 'pingpong',
        'Content-Type': 'application/xml',
    }
})
    .then(res => res.json())
    .then(res => console.log(res));

上面的代码发送 POST 请求,该请求包含了一个非标准的 HTTP X-PINGOTHER 请求标头。这样的请求标头并不是 HTTP/1.1 的一部分,但通常对于 web 应用很有用处。另外,该请求的 Content-Type 为 application/xml,且使用了自定义的请求标头,所以该请求需要首先发起“预检请求”。

HTTP 第六章 跨资源共享(CORS),网络通信,http,网络协议,网络

下面是服务端和客户端完整的信息交互。

首次交互是预检请求/响应
浏览器根据上面的 JavaScript 代码片断所使用的请求参数,向服务端发送一个预检请求,该请求的请求头如下:

OPTIONS /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

标头字段 Access-Control-Request-Method 告知服务器,实际请求将使用 POST 方法。
标头字段 Access-Control-Request-Headers 告知服务器,实际请求将携带两个自定义请求标头字段:X-PINGOTHER 与 Content-Type。

服务器根据预检请求的请求头信息,决定是否允许该实际请求。

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

对于预检请求,不需要响应任何的消息体,只需要在响应头中添加:

  • Access-Control-Allow-Origin:和简单请求一样,表示允许的源
  • Access-Control-Allow-Methods:表示允许的后续真实的请求方法
  • Access-Control-Allow-Headers:表示允许改动的请求头
  • Access-Control-Max-Age:告诉浏览器,多少秒内,对于同样的请求源、方法、头,都不需要再发送预检请求了

预检请求完成之后,发送实际请求

附带身份凭证的请求

XMLHttpRequest 或 Fetch,可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。默认情况下,跨域请求并不会附带cookie。以通过简单的配置就可以实现附带cookie。

// xhr
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

// fetch api
fetch(url, {
  credentials: "include"
})

当一个请求需要附带cookie时,无论它是简单请求,还是预检请求,都会在请求头中添加cookie字段。
服务器响应时,需要明确告知客户端:服务器允许这样的凭据。需要在响应头中添加:Access-Control-Allow-Credentials: true

在响应附带身份凭证的请求时:

  1. 服务器不能将 Access-Control-Allow-Origin 的值设为通配符“*”,而应将其设置为特定的域,如:Access-Control-Allow-Origin: https://example.com。
  2. 服务器不能将 Access-Control-Allow-Headers 的值设为通配符“*”,而应将其设置为标头名称的列表,如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
  3. 服务器不能将 Access-Control-Allow-Methods 的值设为通配符“*”,而应将其设置为特定请求方法名称的列表,如:Access-Control-Allow-Methods: POST, GET

在跨源访问时,浏览器只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

Access-Control-Expose-Headers头让服务器把允许浏览器访问的头放入白名单,例如:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

这样JS就能够访问指定的响应头了。文章来源地址https://www.toymoban.com/news/detail-835777.html

到了这里,关于HTTP 第六章 跨资源共享(CORS)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CORS跨域资源共享漏洞的复现、分析、利用及修复过程

    CORS跨域资源共享漏洞与JSONP劫持漏洞类似,都是程序员在解决跨域问题中进行了错误的配置。攻击者可以利用Web应用对用户请求数据包的Origin头校验不严格,诱骗受害者访问攻击者制作好的恶意网站, 从而跨域获取受害者的敏感数据,包括转账记录、交易记录、个人身份证号

    2024年02月07日
    浏览(87)
  • 第40篇:CORS跨域资源共享漏洞的复现、分析、利用及修复过程

    CORS跨域资源共享漏洞与JSONP劫持漏洞类似,都是程序员在解决跨域问题中进行了错误的配置。攻击者可以利用Web应用对用户请求数据包的Origin头校验不严格,诱骗受害者访问攻击者制作好的恶意网站, 从而跨域获取受害者的敏感数据,包括转账记录、交易记录、个人身份证号

    2024年02月11日
    浏览(27)
  • 前端调用DRI后端API出现跨域资源共享(CORS)问题解决办法

    目录 1. 引言 2. 跨源资源共享和实现方法 3. 在Django项目中配置django-cors-headers库 Reference 在进行后端API开发时,有时会遇到“跨域资源共享 (CORS) 请求...被阻止“的错误,如图1所示。本文讲解如何在使用DRF(Django REST Framework)的后端API开发项目中解决这个问题。 A cross-origin re

    2024年04月25日
    浏览(45)
  • 【burpsuite安全练兵场-客户端13】跨来源资源共享(CORS)-4个实验(全)

       博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员,edusrc高白帽,vulfocus、攻防世界等平台排名100+、高校漏洞证书、cnvd原创漏洞证书,华为云、

    2024年02月02日
    浏览(31)
  • 彻底理解前端安全面试题(3)—— CORS跨域资源共享,解决跨域问题,建议收藏(含源码)

    前端关于网络安全看似高深莫测,其实来来回回就那么点东西,我总结一下就是 3 + 1  = 4,3个用字母描述的【分别是 XSS、CSRF、CORS】 + 一个中间人攻击。当然 CORS 同源策略是为了防止攻击的安全策略,其他的都是网络攻击。除了这 4 个前端相关的面试题,其他的都是一些不常

    2024年02月01日
    浏览(40)
  • Python flask跨域支持(Access-Control-Allow-Origin(CORS)跨域资源共享(访问控制允许来源:允许指定的来源进行跨域请求)浏览器同源策略、OPTIONS预检请求

    浏览器的同源策略(Same-Origin Policy)限制了跨域请求,如果不进行特殊处理,跨域请求将被浏览器拦截。 接口支持跨域能够允许浏览器跨域请求不被浏览器拦截。 下面是跨域请求的一些影响、优点和缺点: 优点 允许不同域名下的应用程序进行数据交互,提高了系统的灵活性

    2024年02月11日
    浏览(33)
  • 【开源】基于JAVA的教学资源共享平台

    基于JAVA+Vue+SpringBoot+MySQL的教学资源共享平台,包含了课程管理、课程课件、授课中心、作业发布、课程评价、课程质量分析、交流互动模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,教学资源

    2024年01月19日
    浏览(49)
  • 云计算资源供应模型是指云计算所提供的资源供应方式,主要包括共享型资源和专属型资源。

    作者:禅与计算机程序设计艺术 云计算是一种将大数据、机器学习等技术应用到互联网的数据中心中,向用户提供更高级的计算服务的一种服务模式。其特点之一就是利用计算机硬件、网络和软件资源池作为计算基础设施(Infrastructure as a Service, IaaS)或平台服务(Platform as

    2024年02月06日
    浏览(36)
  • 【开源】基于JAVA语言的教学资源共享平台

    基于JAVA+Vue+SpringBoot+MySQL的教学资源共享平台,包含了课程管理、课程课件、授课中心、作业发布、课程评价、课程质量分析、交流互动模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,教学资源

    2024年01月20日
    浏览(44)
  • nodejs中的共享资源和锁

    在Node.js中,如果你使用锁来同步代码,通常是为了防止多个线程或进程同时访问共享资源,这可能导致数据不一致或其他问题。然而,Node.js本身并不是一个多线程环境,而是单线程的。因此,你通常不会在Node.js中使用锁来同步线程,而是使用锁来同步异步操作。 如果你正在

    2024年01月22日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包