跨域CORS

概述

同源策略

同源策略(Sameoriginpolicy)是一种约定,它是 浏览器 最核心、最基本 的安全功能。
因此 跨域问题 仅仅存在于 浏览器,走出浏览器 例如 curl、postman 就不存在跨域了。

所谓同源(即指在同一个域)就是两个页面具有相同的 协议(protocol)主机(host)端口号(port)
跨域问题就是当一个请求url的协议、域名、端口三者之间任意一个与 当前页面url 不一致时出现的问题。

跨域脚本攻击

浏览器的同源策略 主要是为了防止 跨域脚本攻击 (Cross Site Scripting,简写作XSS)。

跨域脚本攻击 是 Web应用程序 在将 数据输出 展示到网页的时候 存在问题,导致攻击者可以将对网站的正常功能造成影响甚至窃取或篡改用户个人信息,其诱发的主要原因 是没有 针对用 户输入来源的数据 做安全过滤处理。
跨域脚本攻击的危害性很大,因此开发人员需要注意对用户输入进行严格的过滤和转义,同时浏览器的同源策略也是一种防范跨域脚本攻击的重要手段。

例如,如果一个网站的输入字段没有进行适当的过滤和验证,攻击者可以在表单中插入 JavaScript 代码,当其他用户访问包含这些代码的页面时,该代码就会执行并实施攻击者的恶意意图,比如盗取用户的 cookie 信息、修改页面内容等。

两种请求

浏览器将CORS请求分成两类:简单请求(simple request)和 非简单请求(not-so-simple request)

简单请求

只要同时满足以下两大条件,就属于 简单请求。

1、 请求方法是以下三种方法之一:HEAD、GET、POST

2、 HTTP的头信息不超出以下几种字段:

Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于以下三个值:application/x-www-form-urlencodedmultipart/form-datatext/plain

非简单请求

只要是不同时满足上面 两个条件,就属 非简单请求。

“预检” 请求

非简单请求 的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为 “预检” 请求 (preflight)。
“预检” 请求 的 请求方法 是 OPTIONS

“预检” 请求 的 本质就是 浏览器 询问 服务器:

  • 当前网页所在的 域名 是否在服务器的许可名单之中
  • 当前网页 发出请求的 请求的方法 是否在服务器的许可名单之中
  • 当前网页 发出请求的 请求头字段 是否在服务器的许可名单之中

只有都得到 服务器的 肯定答复,浏览器才会发出正式的XMLHttpRequest请求。

原理讲解

Access-Control-Allow-Origin

该配置是 服务器 回答 客户端 允许 哪些域名 可以跨域访问的。
网上大多在此处的写的是 *,即 允许所有源,这样不安全。
可以指定自己前端的源,例:http://192.121.23.234:3157

Access-Control-Allow-Methods

该配置是 服务器 回答 客户端 允许 哪些请求方法 可以跨域访问的。
可以写常用的方法: GET, POST, PUT, DELETE, PATCH, OPTIONS。
没有写进来的请求方法会出现跨域。

Access-Control-Allow-Headers

该配置是 服务器 回答 客户端 允许 请求头中的哪些字段 可以跨域访问的。
因此需要注意,在前后端交互过程中 如果需要 自定义的请求头,则需在此报备,否则 会报 跨域。

Access-Control-Max-Age

该配置 用来指定 当次 “预检” 请求 的 有效期

  • Access-Control-Max-Age 0
    表示 每次异步请求 都发起 预检请求。

  • Access-Control-Max-Age 60
    表示 该次异步请求 发起 预检请求 后的 60秒内,后续的 非简单请求 都不必在 二次发起 “预检” 请求。

OPTIONS 204
给 OPTIONS 请求 添加 204的返回,是为了处理在发送 非简单请求 时 出现拒绝访问的错误,所以服务器需要允许该方法。

Access-Control-Expose-Headers

该配置 指明 哪些 响应头字段 是可以 让 跨域请求 的 客户端看到的。
默认情况下,使用跨域访问时,浏览器只会返回 默认 6个 响应头字段:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

如果想要 客户端 能够访问其他的请求头,则必须使用 Access-Control-Expose-Headers 列出他们。

Access-Control-Allow-Credentials

该配置 设置是否可以允许发送 cookie
true表示 cookie 包含在请求中,false则相反,默认为false, 也就是会说跨域的请求模式是不会自动携带cookie的。

如果项目需要用到 cookie 就需要设置该字段。CORS请求默认不发送Cookie和HTTP认证信息的,所以在此基础上,也需要在前端设置,这里以axios为例:

 axios.defaults.withCredentials = true

具体实现

Nginx 中的跨域处理

# add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
add_header 'Access-Control-Allow-Headers' 'Origin, x-requested-with, Content-Type, Accept, Authorization';
add_header 'Access-Control-Expose-Headers' 'Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma';
add_header 'Access-Control-Allow-Credentials' 'true';if ($request_method = 'OPTIONS') {add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;
}

Gin 中的跨域处理

package middlewareimport ("net/http""github.com/gin-gonic/gin"
)// 跨域中间件
func Cors() gin.HandlerFunc {return func(context *gin.Context) {method := context.Request.Methodcontext.Header("Access-Control-Allow-Origin", "*")context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")context.Header("Access-Control-Allow-Headers", "Content-Type, AccessToken, X-CSRF-Token, Authorization, Token, Wtt")context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")context.Header("Access-Control-Allow-Credentials", "true")if method == "OPTIONS" {context.AbortWithStatus(http.StatusNoContent)}context.Next()}
}

Flask 中的跨域处理

@app.after_request
def func_res(resp):     res = make_response(resp)res.headers['Access-Control-Allow-Origin'] = '*'res.headers['Access-Control-Allow-Methods'] = 'GET,POST'res.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'return res

SpringBoot

public class CorsFilter implements Filter{@Overridepublic boolean doFilterInternal(HttpServletRequest request, HttpServletResponse response, final FilterChainfilterChain) throws ServletException, IOException{response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,account_id,Origin,Accept,Authorization");response.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");response.setHeader("Access-Control-Max-Age", "1728000");filterChain.doFilter(request, response);}
}

接下来说一下 其他角度 的 跨域处理办法

Vue 反向代理

/*
注意:1、如果使用的 uniapp 自带的网络请求框架, 配置代理则需要在 manifest.json中的 h5 选项中配置,这里 使用的是 第三方网络请求框架 flyio , 配置代理 需要在 vite.config.js 中配置。2、代理 捕获的是 本地项目启动 同源的 请求,例如: npm run dev  启动监听的是 localhost:5612, 那么代理获取的请求的范围 就是 请求地址是 localhost:5612, 然后在通过路径进行 具体捕获。proxy: {'/h5_api': { // 匹配 本地 请求路径 localhost:5173/h5_apitarget: 'http://192.168.104.60:8668', // 代理的目标地址changeOrigin: true, // 开发模式, 默认的origin是 真实的 secure: false, //  是否https接口ws: false, // 是否带来websockets// localhost:5173/h5_api/test   ==> http://192.168.104.60:8663/wtt/testrewrite: (path) => path.replace('/h5_api', '/wtt'),},},*/proxy: {'/api_default': {target: 'http://121.4.225.175:8000', changeOrigin: true,secure: false,rewrite: (path) => path.replace('/api_default', ''),},},},

Nginx 的重定向

# /api_defaul/aaa/bbb   ====>   http://localhost:8033/aaa/bbb
location /api_defaul{proxy_set_header Host $proxy_host;proxy_set_header Real-IP $remote_addr;proxy_set_header name bbb;rewrite ^/api_default/(.*)$  /$1 break; proxy_pass http://localhost:8033;
}

Jsonp

最早的解决方案,利用script标签可以跨域的原理实现。
限制

  • 需要服务的支持
  • 只能发起GET请求

原理:
Jsonp其实就是一个跨域解决方案。Js跨域请求数据是不可以的,但是js跨域请求js脚本是可以的。可以把数据封装成一个js语句,做一个方法的调用。跨域请求js脚本可以得到此脚本。得到js脚本之后会立即执行。可以把数据做为参数传递到方法中。就可以获得数据。从而解决跨域问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/750663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序关闭首页广告

由于之前微信小程序默认开启了首页广告位。导致很多老人误入广告页的内容,所以想着怎么屏蔽广告。好家伙,搜索一圈,要么是用户版本的屏蔽广告,或者是以下一个模棱两可的答案,要开发者设置一下什么参数的,如…

AI预测福彩3D第10弹【2024年3月16日预测--第2套算法重新开始计算第2次测试】

今天继续开始咱们第2套算法的验证,计划每套算法连续测试10期,达到50%的命中率即为较优的模型,可继续使用。老规矩,先上图表,再下结论~ 最终,经过研判分析,2024年3月16日福彩3D的七码预测结果如下…

Stargo 管理部署 Starrocks 集群

配置主机间 ssh 互信 ssh-copy-id hadoop02 ssh-copy-id hadoop03配置系统参数 ############################ Swap检查 ############################ echo 0 | sudo tee /proc/sys/vm/swappiness########################### 内核参数检查 ########################## echo…

外包干了3天,技术明显进步。。。。。

先说一下自己的情况,本科生,19年通过校招进入南京某软件公司,干了接近2年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

【DFS深度优先搜索专题】【蓝桥杯备考训练】:迷宫、奶牛选美、树的重心、大臣的旅费、扫雷【已更新完成】

目录 1、迷宫(《信息学奥赛一本通》) 2、奶牛选美(USACO 2011 November Contest Bronze Division) 3、树的重心(模板) 4、大臣的旅费(第四届蓝桥杯省赛Java & C A组) 5、扫…

Redis分布式锁:共享的秘密花园

嗨,亲爱的读者朋友们!欢迎来到这个充满情感色彩、充满趣味的Redis分布式锁的冒险之旅。今天,我们将一起揭开这个神秘的面纱,深入了解Redis分布式锁是如何成为分布式系统的保护神,保护我们的数据免受混乱的。 分布式的…

JavaWeb笔记 --- 三、MyBatis

三、MyBatis 概述 MyBatis是一个持久层框架,用于简化JDBC Mapper代理开发 在resources配置文件包中创建多级目录用 / MyBatis核心配置文件 enviroments:配置数据库连接环境信息。 可以配置多个enviroment,通过default属性切换不同的envir…

以太网传输图片工程出现的问题总结(含源码)

本文对以太网传输图片的工程曾经出现过的问题及解决思路进行整理,便于日后出现类似问题能够快速处理。也指出为什么前文在FIFO IP设计时为啥强调深度的重要性。 1、问题 当工程综合完毕之后,下载到板子,连接以太网口,相关硬件如下…

源于一区| 改善性能的5种高效而小众的变异策略,一键调用 (Matlab)

基于群体的优化算法在达到迭代后期时种群多样性往往会速降,进化将陷入停滞,而许多算法本身并没有突变机制,一旦受到局部最优值的约束,就很难摆脱这些约束。它还将减少种群多样性,减缓收敛速度。 变异策略可以增加种群…

从嵌套事务的日志看MyBatis的sqlSession生命周期

service层业务代码 Override public void test(){QueryWrapper<StoreRebateCalculateLog> queryWrapper;queryWrapper new QueryWrapper<>();queryWrapper.eq("delete_flag", 0);//执行查询A,A事务开启List<StoreRebateCalculateLog> storeRebat…

股票买卖问题:状态定义的误解与思考

文章目录 问题状态的定义与理解状态定义状态转移函数困惑思考 反思参考资料 问题 股票买卖问题是动态规划中常考的题型&#xff0c;题目一般是给一个 p r i c e s prices prices的数组&#xff0c;每个元素代表当天的股票价格&#xff0c;再给你一个 k k k值&#xff0c;代表允…

pycharm 历史版本下载地址

pycharm 历史版本下载地址 老版本能用就行&#xff0c;不需要搞最新的&#xff0c;当然了&#xff0c;有些小伙伴就是喜欢新的&#xff08;最先吃螃蟹&#xff09; 博主就不搞最新了&#xff0c;哈哈 上菜&#xff1a; https://www.jetbrains.com/pycharm/download/other.html…

01初识Python

一、Python 简介 二、为什么要学Python? 三、Python 安装 四、输出第一条指令 五、总结 一、Python 简介 Python是一种高级编程语言,由Guido van Rossum于1991年创建。它具有简单易学的语法结构,被广泛应用于Web开发、数据科学、人工智能等领域。 Python具有丰富的库…

Windows→Linux,本地同步到服务器

适用背景&#xff1a; 用自己电脑修改代码&#xff0c;使用实验室/公司的服务器炼丹的朋友 优势&#xff1a; 本地 <--> 服务器&#xff0c;实时同步&#xff0c;省去文件传输的步骤 本地改 -> 自动同步到服务器 -> 服务器跑代码 -> 一键同步回本地&#xff…

瑞熙贝通打造智慧校园实验室安全综合管理平台

一、建设思路 瑞熙贝通实验室安全综合管理平台是基于以实验室安全&#xff0c;用现代化管理思想与人工智能、大数据、互联网技术、物联网技术、云计算技术、人体感应技术、语音技术、生物识别技术、手机APP、自动化仪器分析技术有机结合&#xff0c;通过建立以实验室为中心的管…

给你的H5页面加上惯性滚动吧!

在移动端&#xff0c;如果你使用过 overflow: scroll 生成一个滚动容器&#xff0c;会发现它的滚动是比较卡顿&#xff0c;呆滞的。为什么会出现这种情况呢&#xff1f; 因为我们早已习惯了目前的主流操作系统和浏览器视窗的滚动体验&#xff0c;比如滚动到边缘会有回弹&#…

《C缺陷和陷阱》-笔记(5)

目录 一、整数溢出 溢出 如何防止溢出 二、为函数main提供返回值 连接 一、什么是连接器 连接器工作原理 三、声明与定义 四、命名冲突与static 修饰符 statia 一、整数溢出 溢出 C语言中存在两类整数算术运算&#xff0c;有符号运算与无符号运算。 在无…

Redisinsight默认端口改成5540了!网上的8001都是错误的

Redisinsight 打开白屏解决方法 最近发现一个很讨厌的bug&#xff0c;就是redisinsight运行之后&#xff0c;不行了&#xff0c;在网上找到的所有资料里面&#xff0c;redis insight都是运行在8001端口&#xff0c;但是我现在发现&#xff0c;变成了5540 所以对应的docker-com…

七.pandas处理第三方数据

目录 七.pandas处理第三方数据 1.Pandas读取文件 1.1 csv文件操作 1.1.1 CSV文件读取 自定义索引(inde_col) 查看每一列的dtype 更改文件标头名(列的标签) 跳过指定的行数 1.1.2 CSV文件写入 1.2 Excel文件操作 1.2.1 Excel文件读取 1.2.2 Excel文件写入 1.3 SQL操…

mysdql 启动错误 unknown variable windows phpstudy mysql错误日志的正确文件名

1. windowsphpstudy mysql错误日志的正确文件名 log-error"D:/phpstudy_pro/Extensions/MySQL5.7.26/data"。 刚好 数据库文件目录也是"D:/phpstudy_pro/Extensions/MySQL5.7.26/data" 其实对应的错误日志是 D:/phpstudy_pro/Extensions/MySQL5.7.26/dat…