由跨域引发一些思考

由跨域引发一些思考

    • 前言
    • 什么是跨域?
      • 为什么会产生跨域?
      • 跨域场景示例:
      • 跨域常见的解决方法:
        • JSONP(JSON with Padding)
        • CORS(Cross-Origin Resource Sharing)
        • document.domain + iframe
        • location.hash + iframe
        • window.name + iframe
        • postMessage
        • 代理服务器
        • Node.js中间件代理
        • WebSocket
    • 什么是代理?
      • 工作原理
      • 功能与应用
    • 类型
    • 为什么说配置代理能够解决跨域的问题呢?
    • 基于Webpack或者是Vite开发配置代理?
    • 本地开发配置了代理,上线后还需要配置代理么?
    • 小结

前言

最近加了个群,今天有人在群里问了一个问题“前端配置了跨域代理,项目发布到线上还需要配置 nginx 反向代理吗?”,由此,在群里展开了激烈的讨论。讨论的主要点就是在跨域和代理上面,由此引发了我的一些思考。首先记录一些基本的概念。

什么是跨域?

跨域(Cross-Origin)是指在互联网上的一个域下的文档或脚本尝试请求另一个域下的资源时,域名、协议或端口不同的这种行为。由于浏览器实施的同源策略(Same-origin policy),这是一种安全机制,用于限制一个源中的文档或脚本与来自另一个源的资源进行交互,以防止恶意网站读取另一个网站的数据。

为什么会产生跨域?

  1. 同源策略:浏览器的同源策略是为了保护用户信息的安全,它规定了来自一个源的Web内容,只能与同一个源下的资源进行交互。这意味着,如果尝试从不同源加载数据,如使用XMLHttpRequest请求数据,浏览器会默认阻止这种行为,以防恶意站点读取另一个站点的数据。
  2. 安全考量:如果没有同源策略,恶意网站可以通过脚本读取银行网站的cookie信息等敏感数据,造成严重的安全威胁。因此,跨域限制是必要的安全措施。

跨域场景示例:

  • 当前端网页部署在example.com域名下,尝试通过JavaScript向api.example2.com发送Ajax请求获取数据时,就发生了跨域。
  • 即使是同一域名,但端口不同(如example.com:80尝试访问example.com:8080)或者协议不同(HTTPS与HTTP),也会被视为跨域。

跨域常见的解决方法:

JSONP(JSON with Padding)
  • 原理:利用<script>标签没有跨域限制的特性,通过动态创建<script>标签,并设置其src属性为跨域URL(通常包含回调函数名作为参数),来加载并执行跨域脚本。
  • 缺点:只能发送GET请求,存在安全风险(如XSS攻击)。
CORS(Cross-Origin Resource Sharing)
  • 原理:通过服务器设置响应头中的Access-Control-Allow-Origin等字段来允许跨域请求。
  • 支持所有类型的HTTP请求。
  • 需要在服务器端进行配置。
document.domain + iframe
  • 原理:将两个页面的document.domain设置为相同的值,以允许它们通过iframe进行跨域通信。
  • 仅限于主域相同,子域不同的跨域应用场景。
location.hash + iframe
  • 原理:利用iframe的location.hash属性在不同域之间进行数据传递。
  • 需要借助中间页面来实现双向通信。
window.name + iframe
  • 原理:通过iframe的window.name属性在不同域之间共享数据。
  • window.name的值在页面重新加载后依然存在。
postMessage
  • 原理:使用window.postMessage方法可以在不同的窗口(包括iframe)之间安全地传递数据。
  • 需要目标窗口监听message事件来接收数据。
代理服务器
  • 原理:在服务器端设置一个代理服务器,作为中间层来处理跨域请求。
  • 客户端向代理服务器发送请求,代理服务器将请求转发给目标服务器,并将响应返回给客户端。
  • 可以在前端完全避免跨域问题,但增加了服务器端的复杂性。
Node.js中间件代理
  • 原理:在Node.js服务器端使用中间件(如http-proxy-middleware)来代理跨域请求。
  • 客户端向Node.js服务器发送请求,Node.js服务器将请求转发给目标服务器,并将响应返回给客户端。
  • 可以在前端避免跨域问题,但需要搭建Node.js服务器环境。
WebSocket
  • 原理:WebSocket是一种网络通信协议,可以在单个TCP连接上进行全双工通信。
  • 不受同源策略的限制,可以实现跨域通信。
  • 需要服务器端支持WebSocket协议。

什么是代理?

这里的代理其实是指的网络代理。网络代理(Proxy),又称代理服务器,是一种位于客户端和目标服务器之间的中间服务器。以下是关于网络代理的详细解释:
网络代理允许一个网络终端(一般为客户端)通过这个服务与另一个网络终端(一般为服务器)进行非直接的连接。简单来说,它就是网络信息的中转站,代理网络用户去取得网络信息。

工作原理

  • 客户端需要配置代理服务器的地址和端口,然后将网络请求发送给代理服务器。
  • 代理服务器接收请求后,根据客户端的要求进行处理(如更改IP地址、缓存资源等),然后将请求转发给目标服务器。
  • 目标服务器将响应发送给代理服务器,代理服务器再将响应转发给客户端。

功能与应用

  1. 隐私保护:通过使用匿名代理或VPN,用户可以隐藏自己的真实IP地址,防止被目标服务器和网络监听者识别,有助于保护个人隐私和防止网络监控。
  2. 绕过地域限制:有些网络资源会因为地域、政策等原因进行限制。通过使用代理服务器或VPN,用户可以“伪装”成其他地区的IP地址,从而访问受限制的资源。
  3. 负载均衡:对于大型网站和应用,负载均衡是保证高性能和可用性的关键。通过使用反向代理,可以将客户端的请求分发到多个目标服务器,从而实现负载均衡和故障转移。
  4. 内容过滤与审计:企业和学校等组织可以使用HTTP代理对员工和学生的网络访问进行监控和控制,如限制访问特定网站、屏蔽敏感内容等,有助于保证网络安全和合规性。
  5. 网络加速:通过使用缓存代理和CDN技术,可以将网络资源缓存到距离用户更近的服务器上,从而提高访问速度和降低延迟。

类型

  • HTTP代理:能够代理客户机的HTTP访问,主要是代理浏览器访问网页。
  • FTP代理:能够代理客户机上的FTP软件访问FTP服务器。
  • RTSP代理:代理客户机上的Realplayer访问Real流媒体服务器。
  • POP3代理:代理客户机上的邮件软件用POP3方式收发邮件。
  • VPN代理:在共用网络上建立专用网络的技术,通过在公用网络服务商ISP所提供的网络平台之上的逻辑网络来实现。

为什么说配置代理能够解决跨域的问题呢?

配置代理能够解决跨域问题,主要是因为代理服务器在请求发送和接收过程中充当了中间层的角色。以下是详细解释:
中间层的作用:

  • 当客户端发送请求时,请求首先到达代理服务器,而不是直接到达目标服务器。
  • 在代理服务器上,可以将请求中的域名或IP地址进行转换,使得原本不同源的请求在服务器端看起来像是来自同一源的请求。
    解决跨域的原理:
  • 跨域问题本质上是浏览器的一种安全策略,即同源策略(Same-Origin Policy),它禁止不同源的网页之间进行某些交互。
  • 通过配置代理,可以在请求发送之前将请求中的域名转换为目标服务器所接受的域名,从而绕过浏览器的同源策略检查。
  • 例如,如果客户端在localhost:8080下运行,而目标服务器在www.example.com上,客户端发送的请求会首先到达代理服务器。在代理服务器上,可以将请求的域名从localhost:8080转换为www.example.com,然后再将请求转发给目标服务器。
    返回数据的处理:
  • 当目标服务器返回数据时,数据也会首先到达代理服务器。
  • 在代理服务器上,可以将返回数据中的域名从www.example.com转换回localhost:8080(或其他客户端所期望的域名),然后再将数据返回给客户端。

基于Webpack或者是Vite开发配置代理?

我们在平时的前端开发的过程中,通常都会配置代理来解决跨域问题;比如说在Webpack中配置代理:

const { createProxyMiddleware } = require('http-proxy-middleware');  module.exports = {  // ... 其他配置项  devServer: {  proxy: {  '/api': {  target: '<url>', // 目标服务器的地址  ws: true, // 如果你的应用程序使用了websockets,则需要设置为true  secure: false, // 如果你的目标服务器使用了HTTPS,需要设置为false(除非你配置了HTTPS代理)  changeOrigin: true, // 如果你的目标服务器和你的开发服务器不在同一个域上,需要设置为true  pathRewrite: {'^/api' : ''} // 重写路径,例如将/api/users重写为/users  },  // 可以配置多个代理规则  // '/other': { ... }  }  }  
};

在Vite中配置代理:

// vite.config.js  
export default {  // ... 其他配置项  server: {  proxy: {  // 选项写法  '/api': {  target: '<url>', // 目标服务器的地址  changeOrigin: true, // 如果你的目标服务器和你的开发服务器不在同一个域上,需要设置为true  rewrite: (path) => path.replace(/^\/api/, '') // 重写路径,例如将/api/users重写为/users  },  // 或者使用字符串简写  '/foo': '<other_url>'  }  }  
}

本地开发配置了代理,上线后还需要配置代理么?

在本地开发环境中配置代理主要是为了解决跨域问题,允许前端代码能够访问不同源的API服务。然而,当应用程序部署到生产环境后,跨域问题的处理方式会有所不同。
通常,上线后不需要在前端应用中配置代理。 这是因为生产环境中的前端代码通常是通过构建过程(如Webpack、Rollup、Vite等)打包并部署到静态文件服务器或CDN上的,而这些服务器通常不会运行代理服务器。
在生产环境中处理跨域问题的方法主要有以下几种:

  1. 后端服务器配置CORS(跨源资源共享):
    这是最常见的方法。后端服务器配置CORS策略,允许来自特定来源(或所有来源)的跨域请求。前端代码不需要进行任何特殊配置,只需按照正常的HTTP请求方式发送请求即可。
  2. 使用API网关:
    在微服务架构中,API网关通常用于处理跨域请求。API网关可以配置CORS策略,并将请求转发到后端服务。这样,前端代码就可以通过API网关访问后端服务,而无需直接配置代理。
  3. JSONP(仅适用于GET请求):
    虽然JSONP是一种较老的跨域技术,但它仍然在某些情况下被使用。它通过动态插入

小结

在我们前端开发过程中配置了前端代理,当项目上线后,要根据实际的策略来考虑是否需要再远程再配置代理

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

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

相关文章

AutoHotKey自动热键(二)中文版帮助手册下载和自定义一般键盘快捷键

所有的操作其实在开发者手册中已经交待完了,所以我们要使用中文的手册来进行使用 autohotkey1.1.15中文手册下载 好了,为什么有了中文手册,这里还要进行一些具体的介绍呢,就是为了让大家少踩坑,能够快速形成生产力 这里先讲一下自定义快捷键WIN键和ALT键和CTRL键和SHIFT键的组…

智慧的网络爬虫之CSS概述

智慧的网络爬虫之CSS概述 ​ CSS 是“Cascading Style Sheet”的缩写&#xff0c;中文意思为“层叠样式表”&#xff0c;用于描述网页的表现形式。如网页元素的位置、大小、颜色等。css的主要作用是定义网页的样式。 CSS样式 1. 行内样式 行内样式&#xff1a;直接定义在 HT…

深入理解Git:fetch与pull的区别与运用

在Git的版本控制世界中&#xff0c;fetch和pull是两个至关重要的命令&#xff0c;它们都与从远程仓库获取数据有关。然而&#xff0c;这两个命令在功能和用法上却存在着显著的差异。本文将详细解析fetch和pull的区别&#xff0c;以及它们在实际开发中的应用&#xff0c;帮助读者…

Qt 5.14.2+Android环境搭建

1. 安装QT5.14.2的过程中&#xff0c;选中套件&#xff08;kit&#xff09; qt for android。 如果已经安装了qt creator但没有安装该套件&#xff0c;可以找到在qt安装目录下的MaintenanceTool.exe&#xff0c;运行该程序添加套件。 2. 安装jdk8&#xff0c;android sdk&…

五分钟了解MQ消息集成

一、MQ消息集成的定义 MQ消息集成是通过消息中间件&#xff08;Message Queue&#xff09;实现的一种数据集成方式。它通过将数据发送到中间件中&#xff0c;再从中间件中接收数据&#xff0c;实现不同系统之间的数据交换。在MQ消息集成中&#xff0c;发送者和接收者之间不需要…

vue3.2及以上 父调子的方法defineExpose定义供父调用的方法及属性

1、定义子类LoginForm&#xff1a; function handleLogin(account, token) {console.log(account,token)}defineExpose({handleLogin,}); 2、父类调用子类组件 const loginFormRef ref(); <LoginForm ref"loginFormRef" />loginFormRef.value.handleLogin(…

代码随想录第38天|动态规划

1049. 最后一块石头的重量 II 参考 备注: 当物体容量也等同于价值时, 01背包问题的含义则是利用好最大的背包容量sum/2, 使得结果尽可能的接近或者小于 sum/2 等价: 尽可能的平分成相同的两堆, 其差则为结果, 比如 (abc)-d, (ac)-(bd) , 最终的结果是一堆减去另外一堆的和, 问…

Deep-LIBRA:一种用于可靠量化乳腺密度的人工智能方法,并在乳腺癌风险评估中进行了独立验证| 文献速递-深度学习自动化疾病检查

Title 题目 Deep-LIBRA: An artificial-intelligence method for robust quantification of breast density with independent validation in breast cancer risk assessment Deep-LIBRA&#xff1a;一种用于可靠量化乳腺密度的人工智能方法&#xff0c;并在乳腺癌风险评估中…

【LeetCode】每日一题:相交链表

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&am…

7/1 uart

uart4.c #include "uart4.h"//UART4_RX > PB2 //UART4_TX > PG11char rebuf[51] {0}; //rcc/gpio/uart4初始化 void hal_uart4_init() {/********RCC章节初始化*******///1.使能GPIOB组控制器 MP_AHB4ENSETR[1] 1RCC->MP_AHB4ENSETR | (0x1 << 1)…

【C++11:右值引用,列表初始化】

统一列表初始化&#xff1a; 构造函数的函数名与函数体之间增加一个列表&#xff0c;用于对成员初始化 在实例化对象时&#xff0c;支持单/多参数的隐式转化&#xff0c;同时也可以省略符号&#xff0c;让代码更简洁 右值的引用 左值&#xff1a; 左值与右值的重要区别就是能…

全国产化飞腾模块BIOS下修复系统启动文件

1、背景介绍 全国产飞腾模块采用麒麟信安操作系统&#xff0c;当系统下面的grub.cfg文件被用户误操作导致无法启动时&#xff0c;可以在BIOS下通过U盘中备份的grub.cfg替换硬盘上原来的grub.cfg文件&#xff0c;从而实现启动。 2、操作步骤 首先进入BIOS命令行模式&#xff…

Meta低头,库克认错,XR回归第一性原理

图片&#xff5c;Photo by Maxim Hopman on Unsplash ©自象限原创 作者丨罗辑 2024年&#xff0c;XR的故事应该怎么讲&#xff1f; 如果从数据上看&#xff0c;这应该是个沉重的话题。 根据 IDC 报告&#xff0c;2023 年全球 VR 市场出货量下滑了 10.7%。2024 年第一…

【必看】卖惨营销

经常卖惨的人到底是什么心理&#xff1f; Berry Ni同学说&#xff1a; 吸引别人的注意力。想要得到关注。 让你降低对他的期待。 让你能够在他做好一件小事的情况下就表扬他。 控制你对他的想法认知。 ​ 浪矢心理同学说&#xff1a; 1&#xff0c;求关注。他觉得买惨有好处&…

【Excel、RStudio计算T检测的具体操作步骤】

目录 一、基础知识1.1 显著性检验1.2 等方差T检验、异方差T检验1.3 单尾p、双尾p1.3.1 检验目的不同1.3.2 用法不同1.3.3 如何选择 二、Excel2.1 统计分析工具2.1.1 添加统计分析工具2.1.2 数据分析 2.2 公式 -> 插入函数 -> T.TEST 三、RStudio 一、基础知识 参考: 1.…

Gradle学习-4 创建二进制插件工程

二进制插件工程创建有两种方式&#xff1a; 创建独立的工程&#xff0c;调试的时候&#xff0c;需要手动发布成一个二进制插件jar包&#xff0c;给其他工程里面引用&#xff0c;进行功能测试。这种方式是比较麻烦的。创建buildSrc子工程&#xff0c;它是一个大工程中的子工程&…

开源网安荣获第一新声“2024中国最佳信创安全厂商”,信创实力获认可

近日&#xff0c;由权威机构【第一新声】与【天眼查】联合发起的“2024中国最佳信创厂商系列榜单”评选中&#xff0c;开源网安以其技术创新能力和在信创领域持续投入&#xff0c;成功入选“中国最佳信创安全厂商”。 开源网安&#xff0c;作为软件安全领域创领者&#xff0c;自…

数据结构 - C/C++ - 栈

目录 结构特性 结构实现 结构容器 结构设计 顺序栈 链式栈 结构特性 栈(stack)是线性表的一种形式&#xff0c;限定仅在表的一端进行插入或者删除的操作。 栈顶 - 表中允许插入、删除的一端称为栈顶(top)&#xff0c;栈顶位置是可以发生变化的。 插入 - 进栈、入栈、压栈…

数据结构预科

在堆区申请两个长度为32的空间&#xff0c;实现两个字符串的比较【非库函数实现】 要求&#xff1a; 1> 定义函数&#xff0c;在对区申请空间&#xff0c;两个申请&#xff0c;主函数需要调用2次 2> 定义函数&#xff0c;实现字符串的输入&#xff0c;void input(char …

31 C++11

本节目标 c11简介列表初始化变量类型推导范围for循环新增加容器右值新的类功能可变参数模板 1. c11简介 在2003年标准委员会提交了一份计数勘误表&#xff08;简称TC1&#xff09;&#xff0c;使得c03这个名字已经取代了c98称为c11之前的最新的c标准名称。不过由于c03&#x…