✅技术社区—跨域问题及解决方案

一、什么是跨域、为什么会跨域?

我们把问题分解

  • 谁出现的跨域?

==》 浏览器!

  • 为何出现?

==》 同源策略

  • 什么是同源策略?
      • 根据百度百科 同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。
      • 所谓同源 ==》指的是 “协议+域名+端口” 三者的相同 只要有一个不同就会导致跨域问题

所谓同源指的是:

协议、域名、端口号都相同,只要有一个不相同,那么都是非同源。

浏览器在执行脚本的时候,都会检查这个脚本属于哪个页面,即检查是否同源,只有同源的脚本才会被执行;而非同源的脚本在请求数据的时候,浏览器会报一个异常,提示拒绝访问。

①、http://www.123.com/index.html 调用 http://www.123.com/welcome.jsp 协议、域名、端口号都相同,同源。

②、https://www.123.com/index.html 调用 http://www.123.com/welcome.jsp 协议不同,非同源。

③、http://www.123.com:8080/index.html 调用 http://www.123.com:8081/welcome.jsp 端口不同,非同源。

④、http://www.123.com/index.html 调用 http://www.456.com/welcome.jsp 域名不同,非同源。

⑤、http://localhost:8080/index.html 调用 http://127.0.0.1:8080/welcom.jsp 虽然localhost等同于 127.0.0.1 但是也是非同源的。

同源策略限制的情况:

1、Cookie、LocalStorage 和 IndexDB 无法读取

2、DOM 和 Js对象无法获得

3、AJAX 请求不能发送

注意:对于像 img、iframe、script 等标签的 src 属性是特例,它们是可以访问非同源网站的资源的。

二、跨域解决方案

  1. JSONP(JSON with Padding)JSONP是一种非官方的跨域解决方案,通过动态创建<script>标签的方式来绕过同源策略的限制。服务器端需要按照约定好的回调函数格式(jsonobject)返回数据,客户端通过定义同名的回调函数来接收数据。
  • 优点: 兼容性好,支持老版本浏览器。
  • 缺点: 前后端代码耦合度高,只支持GET请求,安全性较差,容易受到XSS攻击。

首先我们要修改 index.jsp 页面的 ajax 请求:

1         $.ajax({2             type:"get",3             async:false,4             url:"http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom",5             dataType:"jsonp",//数据类型为jsonp6             jsonp:"backFunction",//服务端用于接收callBack调用的function名的参数7             success:function (data) {8                 alert(data["passWord"]);9             },
10             error:function () {
11                 alert("error");
12             }
13 
14         });

注意:我们修改了 dataType 的数据类型为 jsonp,并且新增了 jsop 属性值为 “backFunction”。

接着在 项目的 Servlet 中进行如下修改:

1 @WebServlet("/getPassWordByUserNameServlet")2 public class UserServlet extends HttpServlet{3     @Override4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {5         String userName = req.getParameter("userName");6         String passWord = null;7         if(userName != null){8             passWord = "123";9         }
10         JSONObject jsonObject = new JSONObject();
11         jsonObject.put("passWord",passWord);
12         //1、第一种方法:*表示支持所有网站访问,也可以额外配置相应网站
13         //resp.setHeader("Access-Control-Allow-Origin", "*");
14 
15         //2、第二种方法:jsonp
16         String backFunction = req.getParameter("backFunction");
17         resp.getWriter().println(backFunction+"("+jsonObject.toJSONString()+")");
18         
19         //resp.getWriter().println(jsonObject.toJSONString());
20     }
21 }

  1. CORS(Cross-Origin Resource Sharing)是一种机制,它允许来自不同源的Web页面访问服务器上的资源,解决了由于浏览器的同源策略而引起的跨域访问限制问题。CORS 通过在服务器端添加特定的HTTP响应头,来告知浏览器允许来自特定源的Web应用访问服务器上的资源。
  • 优点: 支持所有类型的HTTP请求,安全性较高。
  • 缺点: 老版本浏览器不支持。
  • CORS 通信过程都是浏览器自动完成的,不需要用户参与
  • 对于开发者一样,CORS 通信与普通的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨域,就会自动添加一些附加的头信息
  • 因此 实现CORS的关键是服务器,只要服务器实现了CORS接口 就可以跨域通信

工作原理

  • 当一个Web应用尝试发起一个跨源请求时(例如,使用 XMLHttpRequest 或 Fetch API),浏览器会自动在请求中添加一个 Origin 头,该头包含了发起请求的页面的源信息(协议、域名和端口)。服务器接收到请求后,会检查 Origin 头,并根据自身的CORS策略决定是否允许该跨源请求。
  • 如果服务器允许该请求,它会在响应中添加一个 Access-Control-Allow-Origin 头,该头的值可以是 *(表示允许所有源)或者是与请求中 Origin 头相匹配的特定源。浏览器接收到响应后,会检查 Access-Control-Allow-Origin 头,如果源被允许,浏览器就会处理响应;如果不被允许,浏览器会阻止响应,并抛出一个错误。

后端需要做的工作

  • 分为三个场景
  • 专门支持某个接口跨域:通过@CrossOrigin注解

  • 批量支持某一批接口跨域:实现一个Web MVC Configure 这样的一个Bean,重写跨域的映射的方法,通过注册器来添加那一批接口可以实现跨域

  • 支持所有接口都跨域:设置一个过滤器来限制所有接口跨域请求

  1. 代理服务器 使用代理服务器(如 Nginx)进行请求转发是一种常见的解决跨域问题的方法。通过配置代理服务器,可以使客户端请求看起来像是发往同源服务器,而实际上是由代理服务器转发到目标服务器。这样就绕过了浏览器的同源策略限制。
  • 优点: 可以解决所有跨域问题,安全性较高。
  • 缺点: 需要服务器端额外配置和维护。

使用代理服务器(如 Nginx)进行请求转发是一种常见的解决跨域问题的方法。通过配置代理服务器,可以使客户端请求看起来像是发往同源服务器,而实际上是由代理服务器转发到目标服务器。这样就绕过了浏览器的同源策略限制。

工作原理

  1. 客户端请求:客户端(例如浏览器)发送一个请求到代理服务器,这个请求的URL看起来是同源的,因为它指向代理服务器所在的域。
  2. 代理转发:代理服务器接收到请求后,根据配置将请求转发到实际的目标服务器。这个转发过程对客户端是透明的。
  3. 目标服务器响应:目标服务器处理请求并返回响应给代理服务器。
  4. 代理返回响应:代理服务器再将目标服务器的响应转发回客户端。

Nginx 配置示例

假设有一个前端应用部署在 http://www.example.com 上,需要访问一个部署在 http://api.another-domain.com 的后端API。可以在 Nginx 中配置一个代理来实现跨域请求:

server {listen 8081;server_name www.example.com;location /api/ {proxy_pass http://api.another-domain.com/;//只要是前缀是api的请求都转发到这个地址zproxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
}

在这个配置中:

  • server_name 指定了前端应用的域名。
  • location /api/ 指定了一个路径,所有以 /api/ 开头的请求都会被转发。
  • proxy_pass 指定了目标服务器的地址。
  • proxy_set_header 指令用于设置请求头,这些请求头会被转发到目标服务器。

使用场景

代理服务器的跨域解决方案适用于以下场景:

  • 开发环境:在本地开发时,可以使用代理服务器将前端请求转发到后端API,避免跨域问题。
  • 生产环境:在生产环境中,可以使用代理服务器来统一前端和后端的域名,从而避免跨域问题。
  • 跨域资源共享:当需要访问第三方服务或API时,可以通过代理服务器进行请求转发,实现跨域资源的访问。

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

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

相关文章

Linux 时间系统调用

UNIX及LinuxQ的时间系统是由「新纪元时间」Epoch开始计算起。Epoch是指定为1970年1月1日凌晨零点零分零秒&#xff0c;格林威治时间。目前大部份的UNX系统都是用32位来记录时间&#xff0c;正值表示为1970以后&#xff0c;负值则表示1970年以前。 对于当前时间到Epoch 我们用两…

代码算法训练营day10 | 232.用栈实现队列、225. 用队列实现栈

day10: 232.用栈实现队列225. 用队列实现栈 232.用栈实现队列 题目链接 状态&#xff1a; 文档&#xff1a;programmercarl.com 思路&#xff1a; 用栈实现队列。要先明白两者的区别。 栈&#xff1a;单开门&#xff0c;先进后出&#xff0c;只有一端能进出。 队列&#xff1a;…

继承 ResponseEntityExceptionHandler

目录 作用概述 示例-HttpRequestMethodNotSupportedException 示例-自定义异常处理 总示例 使用了ResponseEntityExceptionHandler后&#xff0c;为什么发生了异常后返回体为空 方法执行顺序 作用概述 这是一个方便的基类&#xff0c;用于希望通过 ExceptionHandler 方法…

Vue项目的搭建

Node.js 下载 Node.js — Download (nodejs.org)https://nodejs.org/en/download/ 安装 测试 winR->cmd执行 node -v配置 在安装目录下创建两个子文件夹node_cache和node_global,我的就是 D:\nodejs\node_cache D:\nodejs\node_global 在node_global文件下再创建一个…

并查集(详解+例题)

1、作用 将两个集合合并 询问两个元素是否在一个集合中 2、基本原理 每个集合用一颗树表示。树根的编号就是整个集合的编号。每个节点存储它的父节点&#xff0c;p[x]表示x的父节点。 3、实现 问题1&#xff1a;如何判断树根&#xff1a;if(p[x]x); 问题2&#xff1a;如何求…

C++ 特殊类及单例模式

文章目录 1. 前言2. 不能被拷贝的类3. 不能被继承的类4. 只能在堆上创建对象的类5. 只能在栈上创建对象的类6. 只能创建一个对象的类&#xff08;单例模式&#xff09; 1. 前言 在实际场景中&#xff0c;我们在编写类的过程中总会遇到一些特殊情况&#xff0c;比如设计一个类不…

深入解析红黑树(RB-Tree):原理、操作及应用

文章目录 一、红黑树的特点与性质二、红黑树的实现1、实现红黑树的插入操作2、红黑树的验证方法a. Check 函数b. IsBalance 函数 红黑树作为一种自平衡的二叉搜索树&#xff0c;在计算机科学领域中占据着重要的地位。它的设计旨在在维持树的平衡性的同时&#xff0c;保证各种操…

红队攻防之exe文件签名免杀

达则兼善天下&#xff0c;穷则独善其身 1、生成 cobaltstrike bin文件&#xff0c;选择raw选项。 2、使用 cobaltstrike分离免杀工具生成loader.exe文件。 3、使用UPX对生成的exe文件进行加壳&#xff0c;加壳前后对比文件的大小。 4、对loader.exe进行制作并签发证书-数字签名…

UDF提权

目录 一、UDF概述 二、提权条件 三、漏洞复现 (一) 信息收集 1. Nmap信息收集 1.1、查看当前IP地址 1.2、扫描当前网段&#xff0c;找出目标机器 1.3、快速扫描目标机全端口 2. dirb目录扫描 3. 第一个flag 3.1、目录遍历漏洞 3.2、flag 4. 敏感信息利用 (二) 漏…

ElasticSearch常见用法,看这一篇就够了(文末送书)

2024送书福利正式起航 关注「哪吒编程」&#xff0c;提升Java技能 文末送3本《一本书讲透Elasticsearch&#xff1a;原理、进阶与工程实践》 大家好&#xff0c;我是哪吒。 ElasticSearch是一款由Java开发的开源搜索引擎&#xff0c;它以其出色的实时搜索、稳定可靠、快速安…

土壤水分实测数据网站资源

农田土壤水分数据 貌似是站点数据&#xff0c;但是年份太老&#xff0c;而且也没找着下载的地方 2012年黄土高原土壤水分及相关土壤物理参数数据集 2007-2009年中国农业大学石羊河实验站玉米通量与生长观测数据集 2005&#xff5e;2014年CERN野外台站气象观测场土壤含水量数据…

一维差分(模板)

差分是前缀和的逆运算&#xff0c;对于一个数组a&#xff0c;其差分数组b的每一项都是a [ i ]和前一项a [ i − 1 ]的差。 注意&#xff1a;差分数组和原数组必须分开存放&#xff01;&#xff01;&#xff01;&#xff01; #include <iostream> using namespace std;t…

【回归预测】基于SSA-BP(麻雀搜索算法优化BP神经网络)的回归预测 多输入单输出【Matlab代码#69】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】1. BP神经网络2. 麻雀搜索算法3. SSA-BP神经网络模型的构建4. 部分代码展示5. 仿真结果展示 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】 1. BP神经网络 BP&…

算法:一些DFS的经验

DFS:可以看作是向下遍历树的模拟 剪枝&#xff1a;减少时间复杂度 一个dfs所需要具备的元素&#xff1a; 一&#xff0c;出口 1.出口&#xff1a;每一个进入的dfs的出口&#xff0c;可以是枚举全部元素后退出该dfs,也可以是大于层数或剪枝条件........ 二&#xff0c;向下搜…

Linux:系统初始化,内核优化,性能优化(3)

优化系统的文件句柄数&#xff08;全局&#xff09; 也就是系统的最大文件数量 查看最大数量 cat /proc/sys/fs/file-max 当我们的服务器有非常大的一个数据并发的时候十几二十万的文件需要去配置&#xff0c;可能这个是远远不够的&#xff0c;我们就要去修改 vim /etc/sy…

springboot换日志框架后爆SLF4J: Class path contains multiple SLF4J bindings的解决办法

sringboot原本使用的是logback日志框架&#xff0c;将它去掉&#xff0c;修改为log4j2日志框架后&#xff0c;往往会出现以下错误&#xff1a; SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/C:/Users/admin/.m2/repository/ch/qos…

NuGet程序包管理器

文章目录 1.为什么要用包管理工具&#xff1f;2.常用的包管理工具3.Net中的包管理工具4.使用方式4.1 命令行使用4.2 图形界面 5.Tips 1.为什么要用包管理工具&#xff1f; 开发过程中几乎不可避免地要使用第三方包&#xff0c;当然可以不用包管理器。对于开源的项目可以直接引用…

稀碎从零算法笔记Day20-LeetCode:回文链表

题型&#xff1a;链表、双指针 链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 234. 回文链表 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述&#xff08;红字为笔者添加&#xff09; 给你一个单链表的头节点 head &…

基于Python的口罩佩戴识别的设计与实现(UI界面+MySQL数据库+YOLOv5+训练数据集+开题报告+中期检查+论文)

摘要 本文旨在基于Python开发一种口罩佩戴识别系统&#xff0c;通过深度学习技术实现对口罩佩戴情况的准确检测。采用了YOLOv5系列目标检测算法作为基础模型&#xff0c;并结合迁移学习进行训练和优化。同时&#xff0c;为了提供更好的用户体验&#xff0c;本系统还设计…

代码算法训练营day9 | 28. 实现 strStr() 、459.重复的子字符串

day9&#xff1a; 28. 实现 strStr()KMP的主要应用&#xff1a;什么是前缀表&#xff1a;前缀表是如何记录的&#xff1a; 如何计算前缀表&#xff1a;构造next数组&#xff1a;1、初始化2、处理前后缀不相同的情况3、处理前后缀相同的情况 代码&#xff1a; 459.重复的子字符串…