架构设计-跨域问题的根源及解决方式

news2024/12/27 11:07:19

前面文章《架构设计-web项目中跨域问题涉及到的后端和前端配置》中说明了处理跨域问题的一种方式,本文详细说明下产生跨域问题的原因及处理方式。

一、产生跨域问题的原因:

浏览器的同源策略:这是跨域问题的根本原因。同源策略是浏览器对JavaScript施加的安全限制,目的是出于浏览器安全考虑,防止恶意网站窃取数据。所谓“同源”指的是协议、域名、端口号都相同,只要有一个不相同,则被视为非同源。

跨域就是在浏览器请求资源的过程中发生的。

二、 解决跨域问题的常用方式:

1. JSONP  (Json With Padding)

利用了 script 标签没有跨域限制的特性,通过 src 属性发送一个带回调参数的 get 请求,实现跨域。

一种略显古老的处理方式

$.ajax({
   type : "GET",
   url : "http://abc.com/detail/",
   data:"id=100",
   dataType:"jsonp",
   jsonp:"callback",
   jsonpCallback:"showDetail",
   success : function(data){
	   alert("ok");
   },
   error : function(data){
   	   alert("no");
   }
});

以上代码转换成 dom 文档

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script type='text/javascript'>
      // 后端返回直接执行的方法,相当于执行这个方法,由于后端把返回的数据放在方法的参数里,所以这里能拿到res。
      window.showDetail = function (res) {
        console.log(res)
        // ajax回调
      }
    </script>
    <script src='http://abc.com/detail?id=100&callback=showDetail' type='text/javascript'></script>
  </body>
</html>

页面的 src 标签访问 abc.com 的服务端资源,由于 <script/> 标签不受 xmlHttpRequest 限制,后端接收到请求后返回约定好的 json 对象

showDetail({
	status: 0,
	result: {
		id: 1,
		name: "san",
		price: 99.9,
		level: 2
	}
})

接下来,浏览器执行 showDetail 的过程,就相当于执行了上面定义的 window.showDetail 方法并传入了后端返回的 json ,然后可以应用到 success 方法中。

2. CORS

跨域资源共享。Cross-Origin Resource Sharing  后端人员在返回客户端的数据上加上对应的响应头,告知浏览器可以放行此数据给客户端。

对 http 的 response 属性配置头部信息:

@Component
public class CorsFilter implements WebFilter {

    private static final String ALL = "*";
    private static final String MAX_AGE = "3600L";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // 非跨域请求,直接放行
        ServerHttpRequest request = exchange.getRequest();
        if (!CorsUtils.isCorsRequest(request)) {
            return chain.filter(exchange);
        }

        // 设置跨域响应头
        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.add("Access-Control-Allow-Origin", ALL);
        headers.add("Access-Control-Allow-Methods", ALL);
        headers.add("Access-Control-Allow-Headers", ALL);
        headers.add("Access-Control-Max-Age", MAX_AGE);
        if (request.getMethod() == HttpMethod.OPTIONS) {
            response.setStatusCode(HttpStatus.OK);
            return Mono.empty();
        }
        return chain.filter(exchange);
    }

}

注意:

Access-Control-Allow-Credentials 属性只有当需要跨域进行 cookie 传递时才需要设置为 true,并且需要前端配置 withCredentials: true 时才能跨域传递 cookie。另外 safari 和最新版本的 chrome浏览器还需要在设置内放开对应限制, 当这个参数被设置成 true ,Access-Control-Allow-Origin就不能设置为 * ,否则就变成任何origin域都能允许传递 cookie ,存在安全隐患。

如果使用了 nginx 反向代理,可以直接在 nginx 反向代理上配置

location /{
	proxy_pass http://abc.com;

	add_header Access-Control-Allow-Methods *;
	add_header Access-Control-Allow-Credentials true;
	add_header Access-Control-Allow-Origin $http_origin;
	add_header Access-Control-Allow-Headers *;
	
}

3. Proxy

  • 使用 vue-cli 的跨域代理配置。

本质是通过 代理服务器 充当 本地请求 和 目标服务器 之间的桥梁,代理服务器 和 本地浏览器 同源,不存在跨域,所以浏览器能正常接收数据,通过避开浏览器的同源策略完成跨域请求。

server: {
    port: 3000, // 设置服务启动端口号
    open: true, // 设置服务启动时是否自动打开浏览器
    host: "0.0.0.0",
    proxy: {
      '^/order': {
        target: config.VITE_ORDERURL,
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/order/, ''),
      },
      '^/sale': {
        target: config.VITE_SALEURL,
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/sale/, ''),
      },
     
    },
  }
  • 使用 nginx 可以这样配置。

如果静态页面在 xyz.com 上,动态请求访问 pqm.com ,将对应服务部署在不同机器上,使用公共的 abc.com 域名 作为 nginx 反向代理的入口,再将 静态服务、动态服务 分别挂在被代理局域网服务器内。

server{
	listen:80;
	server_name: abc.com;

	# 静态资源
	location /{
		proxy_pass http://xyz.com/;
	}

	# 动态请求
	location /api{
		proxy_pass http://pqm.com/;

	}

}

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

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

相关文章

C语言 sizeof 和 strlen

目录 一、sizeof 和 strlen 的区别 a.sizeof b.strlen c.sizeof与strlen的区别 二、数组和指针笔试题解析(32位环境) a.一维数组( int a[ ] { 1 , 2 , 3 , 4 } ) b.字符数组 &#xff08;char arr[ ] {a , b , c , d , e , f }&#xff09; &#xff08; char arr[ …

吴恩达2022机器学习专项课程C2W3:实验Lab_01模型评估与选择

这里写目录标题 导入模块与实验环境配置回归1.构建并可视化数据集2.分割数据集3.重新绘制数据集3.特征缩放4.评估模型&#xff1a;计算训练集的误差5.评估模型&#xff1a;计算交叉验证集的误差 添加多项式1.构建多项式特征集2.缩放特征3.使用标准化的计训练集和交叉验证集&…

[next.js]移动端调试vconsole

一般最简单的调试方式当然是使用vconsole来输出想要的数据啦&#xff1b; next.js如果想使用的话需要在客户端环境里调用才行&#xff08;服务端直接看cmd控制台就够了&#xff09;&#xff1b; 先安装vconsole npm i -D vconsolenext.js不像react cli或者vue一样有一个main.…

Python学习从0开始——Kaggle计算机视觉001

Python学习从0开始——Kaggle计算机视觉001 一、卷积分类器1.分类器2.训练分类器3.使用 二、卷积和RELU1.特征提取2.带卷积的过滤器定义3.激活&#xff1a;4.用ReLU检测5.使用 三、最大池化1.最大池压缩2.使用3.平移不变性 四、滑动窗口1.介绍2.步长3.边界4.使用 五、自定义Con…

[linux]如何跟踪linux 内核运行的流程呢

前面已经可以把内核编译出来&#xff0c;但是作为技术狗想看到内核是怎么运行的怎么办&#xff1f; 内核很多代码都是C语言写的&#xff0c;那简单&#xff0c;添加2行代码&#xff1a; include/linux/printk.h 529和530原来的&#xff1a; #define pr_info(fmt, ...) \ …

Vue07-MVVM模型

一、MVVM模型的定义 M&#xff1a;模型&#xff08;model&#xff09;&#xff1a;对应data中的数据&#xff1b;V&#xff1a;视图&#xff08;view&#xff09;&#xff1a;模版&#xff1b;VM&#xff1a;视图模型&#xff08;ViewModel&#xff09;Vue的实例对象。 Vue.js…

计算机网络 —— 运输层(UDP和TCP)

计算机网络 —— 运输层&#xff08;UDP和TCP&#xff09; UDPTCPUDP和TCP的异同点相同点不同点 我们今天来看运输层的两个重要的协议——UDP和TCP UDP UDP&#xff0c;全称为用户数据报协议&#xff08;User Datagram Protocol&#xff09;&#xff0c;是互联网中一种核心的…

探地雷达正演模拟,基于时域有限差分方法,三

回顾上一章内容&#xff0c;主要讲了FDTD及基于C的实现方式和边界条件处理&#xff0c;这一章主要内容有两点&#xff1a;1、基于实际操作流程的GPR正演模拟&#xff08;宽角法和剖面法&#xff09;&#xff1b;2、简单并行化加速GPR正演模拟&#xff08;基于OpenMP&#xff09…

Mybatis Log Free

安装后重启 在 application.yml 配置 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 选择效果

搭建一个简单的深度神经网络

目录 一、引入所需要的库 二、制作数据集 三、搭建神经网络 四、训练网络 五、测试网络 本博客实验环境为jupyter 一、引入所需要的库 torch库是核心&#xff0c;其中torch.nn 提供了搭建网络所需的所有组件&#xff0c;nn即神经网络。matplotlib类似与matlab&#xff0…

Apple Intelligence全面来袭,熟悉但又不同的味道

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

618购物节入手哪些数码好物好?年度必备好物清单大盘点

随着一年一度的618购物节的到来&#xff0c;数码市场再次掀起了热潮&#xff0c;在这个属于消费者的狂欢节里&#xff0c;各大品牌和商家纷纷推出优惠活动和新品&#xff0c;为数码爱好者们带来了无数的购物选择&#xff0c;那么在这个购物盛宴中&#xff0c;我们应该如何挑选那…

如何进行论文查重,选择合适的查重系统?

原创性是学术写作海洋中的航行灯塔&#xff0c;而论文查重&#xff08;www.check110.com&#xff09;则是保障这束光芒不被云雾遮蔽的工具。而查重系统如何对论文进行查重&#xff0c;又该如何选择论文查重系统呢&#xff1f; 一、论文查重 论文查重&#xff0c;就是检测学术…

Python基础教程(十三):file文件及相关的函数

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

idea中使用逆向工程生成数据库表的实体类

1、在idea中打开数据库视图&#xff1b; 2、点击database中的号创建数据源连接&#xff08;以MySQL为例&#xff09;&#xff1b; 填入账户密码以及数据库名&#xff1b; 点击测试连接&#xff0c;若出现爆红Server returns invalid timezone. Go to Advanced tab and set serv…

RawChat:优化AI对话体验,全面兼容GPT功能平台

文章目录 一、Rawchat简介1.1 RawChat的主要特性1.2 RawChat的技术原理简述 二、使用教程三、案例应用3.1 图片内容分析3.2 生图演示3.3 文档解析3.4 探索更多 四、小结 一、Rawchat简介 RawChat平台的诞生&#xff0c;其核心理念是降低用户访问类似ChatGPT这类先进AI服务的门…

MySQL复习题(期末考试)

MySQL复习题&#xff08;期末考试&#xff09; 1.MySQL支持的日期类型&#xff1f; DATE,DATETIME,TIMESTAMP,TIME,TEAR 2.为表添加列的语法&#xff1f; alter table 表名 add column 列名 数据类型; 3.修改表数据类型的语法是&#xff1f; alter table 表名 modify 列名 新…

文心智能体体验,打造你自己的GPTs应用

利用百度智能体搭建的《RPG冒险游戏大作战》已经发布啦&#xff01; RPG冒险游戏大作战 玩家扮演一位小小勇士女孩&#xff0c;从被巨龙毁灭的冒险小镇出发&#xff0c;一路披荆斩棘&#xff0c;集齐四件神器后&#xff0c;打败巨龙&#xff0c;夺回小镇的安宁&#xff01; 整…

python3的基本语法说明一

一. 简介 本文开始学习 python3 的基本语法。 二. python3的基本语法 1. 编码 默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c;所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码&#xff1a; # -*- coding: cp-1252 -*- 上述…

Unity图集

概述 相信在同学们学习过程中&#xff0c;在UI的的使用时候一定经常听说过图集的概念。 Unity有UI的组件&#xff0c;有同学们好奇&#xff0c;那为什么还要使用图集呢&#xff1f; 这就需要提到一个性能优化的问题了&#xff0c;因为过多的UI图片&#xff0c;会大幅增加Dra…