首页 > 其他分享 >架构设计-跨域问题的根源及解决方式

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

时间:2024-06-11 18:04:38浏览次数:10  
标签:Control 架构设计 浏览器 跨域 Access Allow 根源 com

前面文章《架构设计-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/;

	}

}

标签:Control,架构设计,浏览器,跨域,Access,Allow,根源,com
From: https://blog.csdn.net/suiusoar/article/details/139598100

相关文章

  • 深入探讨跨域请求(CORS):原理、解决方案与详细示例代码
    深入探讨跨域请求(CORS):原理、解决方案与详细示例代码......
  • 架构设计-全局异常处理器404、405的问题
    javaweb项目中经常会遇到异常处理的问题,普遍的做法是使用全局异常处理,这样做有以下几种原因:集中化处理:全局异常处理允许你在一个集中的地方处理整个应用程序中的异常。这有助于减少代码重复,因为你不必在每个可能抛出异常的方法中都编写相同的异常处理代码。统一错误响应:通过......
  • 架构设计-web项目中跨域问题涉及到的后端和前端配置
    WEB软件项目中经常会遇到跨域问题,解决方案早已是业内的共识,简要记录主流的处理方式:跨域感知session需要解决两个问题:1.跨域问题2.跨域cookie传输问题跨域问题解决跨域问题有很多种方式,如使用springboot自带的crossOrigin注解@CrossOrigin(origins={"*"},allowedHe......
  • 软考 系统架构设计师系列知识点之杂项集萃(32)
    接前一篇文章:软考系统架构设计师系列知识点之杂项集萃(31)第51题网络逻辑结构设计的内容不包括()。A.逻辑网络设计图B.IP地址方案C.具体的软硬件、广域网连接和基本服务D.用户培训计划正确答案:D。所属知识点:旧版教材计算机网络->网络规划与设计解析:逻辑网络设计......
  • 软考 系统架构设计师系列知识点之杂项集萃(33)
    接前一篇文章:软考系统架构设计师系列知识点之杂项集萃(32)第53题企业信息集成按照组织范围分为企业内部的信息集成和企业外部的信息集成。在企业内部的信息集成中,()实现了不同系统之间的互操作,使得不同系统之间能够实现数据和方法的共享;()实现了不同应用系统之间的连接、协调运......
  • nginx配置跨域文档记录
    参考:https://www.cnblogs.com/PengfeiSong/p/12993446.html@目录概要代码小结概要这个跨域我之前配置过,昨天搜了下教程没有配成功,今天上午又花了近一上午才搞定,特意过来记录下代码server{listen80;server_nameapi.xxx.space;client_max_body_size50M;......
  • 前端怎么解决跨域问题
    前端跨域问题的解决方案通常涉及几种不同的方法,每种方法都有其特定的应用场景和优缺点。以下是一些常见的前端跨域解决方案:JSONP(JSONwithPadding)原理:利用<script>标签没有跨域限制的特性,通过动态创建<script>标签并设置其src属性为跨域请求的URL,来实现跨域数据获取。实现方......
  • nginx /Java 解决跨域问题方案
    location/{#if($request_method='OPTIONS'){#add_header'Access-Control-Allow-Origin''*';#add_header'Access-Control-Allow-Methods''GET,POST,OPTIONS';......
  • 跨域问题的原因以及解决方案有那些
    跨域问题的原因主要是浏览器的同源策略。同源策略是浏览器的一种安全策略,它要求协议、域名、端口三者必须完全一致,否则就会被浏览器视为跨域请求,从而限制其执行。具体来说,跨域问题的原因有以下几点:1、Cookie、LocalStorage和IndexDB无法读取:由于跨域请求的限制,浏览器无......
  • 深入跨域 - 解决方案
    1前言前文《深入跨域-从初识到入门》中,大家已经对同源与跨域的产生历史与重要性等有了一个初步的了解了,那么我们应该如何解决在日常开发中遇到的跨域引起的问题呢? 2一览图我们将日常开发中的跨域解决方案大体分为两类:iframe跨域与API跨域:       ......