当前位置: 首页> 健康> 美食 > 架构设计-跨域问题的根源及解决方式

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

时间:2025/8/27 13:31:03来源:https://blog.csdn.net/suiusoar/article/details/139598100 浏览次数:0次

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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: