不同角度看跨域那些事

本文涉及的产品
.cn 域名,1个 12个月
简介: 前沿:跨域是一个老生常谈的话题,树酱在github上无意间看到cors-anywhere这个开源库,加上最近身边有一些实习童鞋在本地开发环境中提出疑惑🤔,本地开发是如何解决跨域问题的?结合以上,也就有了今天的主题,前端跨域解决方案那些事。跨域解决方案比较多,🌲酱君把平时接触比较多的share一下

微信截图_20220514173538.png


前沿:跨域是一个老生常谈的话题,树酱在github上无意间看到cors-anywhere这个开源库,加上最近身边有一些实习童鞋在本地开发环境中提出疑惑🤔,本地开发是如何解决跨域问题的?结合以上,也就有了今天的主题,前端跨域解决方案那些事。跨域解决方案比较多,🌲酱君把平时接触比较多的share一下


微信截图_20220514173625.png


1.什么是跨域?


首先我们先看看下面这个列子


微信截图_20220514173636.png


这个就是典型的跨域问题,那为何会跨域?是因为浏览器的安全功能“同源策略”,它限制了两个不同源之间的数据访问以及交互,因为不同源,浏览器限制访问不到。本质上是一个安全机制,为了防止程序恶意调用。


2.同源策略


工欲善其事,必先利其器。想要更好地理解跨域,那就要梳理好同源策略,而所谓同源就是指,域名,协议,端口相同,看看下面这个经典演示图,对比下访问 http://a.tree.com的同源检测


Url 结果 原因
b.tree.com 不成功 不同域名
a.tree.com:81/home 不成功 不同端口
a.tree.com/home 不成功 不同协议(http https)
a.tree.com/user 成功 域名,协议,端口相同


换句话说:影响是否跨域的3个因素:协议+域名+端口


但是我就是要请求不同源的!咋搞?微信截图_20220514173652.png


3.如何解决浏览器存在的跨域问题?


这个时候就是我们熟悉的CORS出场,CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),CORS的存在使得浏览器向跨源服务器,发出XMLHttpRequest请求。他是怎么让原本僵持不下的浏览器童鞋和服务器童鞋,成功牵手👫的呢? but 也需要两个人的共同努力,主要需要下面两个方面的改造


  • 👦 服务器: 需要实现了CORS接口,就可以跨源通信
  • 👧 浏览器:需要在请求头加上一些头信息


CORS背后的基本思想是通过使用自定义的HTTP头部允许浏览器和服务器了解对方,从而决定请求是否成功响应,而决定是否成功关键步骤就在于“预检”


啊呆同学:我们平时看到我们控制台Network中一个接口会出现两次调用,其中一次是OPTIONS请求,这个是啥?


答:这就是个预检操作。对于非简单请求,会在真正发起请求之前,发起一次HTTP查询请求(OPTIONS请求),即"预检"请求。预检的目的就是看看浏览器童鞋和服务器童鞋是否牵手成功,浏览器童鞋会先询问服务器童鞋,目前发起请求的域名是否在服务器的白名单中,如果在,浏览器才会真正才会发起正式的XMLHttpRequest请求


啊呆同学:那他们是如何检测是否牵手成功?


答:主要包括CORS相关的HTTP头部有:


客户端发送


  • Origin:请求来自哪个源
  • Access-Control-Request-Method:浏览器的CORS请求会用到哪些HTTP方法
  • Access-Control-Request-Headers: CORS请求会额外发送的头信息字段


服务端接受后,检查👆以上相关字段,然后回应下面👇其他CORS相关字段


  • Access-Control-Allow-Origin:表示服务端允许的源
  • Access-Control-Allow-Headers:表示表明服务器支持的所有头信息字段
  • Access-Control-Allow-Methods: 表明服务器支持的所有跨域请求方法


我们看看下面这个例子,使用Nginx做的静态资源CORS支持,通过add_header增加http响应头


微信截图_20220514173709.png


啊芬同学:以前不是都用JSONP吗,两者有什么区别?


答:目的相同,但JSONP仅使用与GET请求,而CORS支持所有类型的HTTP请求,而且JSONP主要支持的浏览器都是“老古董”,而现在绝大多数的浏览器都是支持CORS的


🌲 拓展阅读:


4.服务端角度去解决跨域原理


如果有个需求,需要你去调用第三方的API或者资源,但第三方并没有将你的Orgins设置到Access-Control-Allow-Origin头信息中去,那你是无法获取第三方数据资源的,那上面的办法行不通,这种情况该怎么解决?


你可以通过node中间件实现跨域代理,原理大致与上一节提到nginx相同,就是通过启一个代理服务器,实现数据的的转发来完成,简而言之就是在客户端和第三方服务中间再加一个“代理商”,让这个代理商去第三方获取再返回给客户端


4.1 CORS Anywhere


CORS Anywhere是一个NodeJS反向代理,它将CORS标头添加到代理请求中文档链接


他提供了一个在线的使用版本:https://cors-anywhere.herokuapp.com/://example.com,他的流程是这样,看下图所示👇


微信截图_20220514173722.png


本质上是一个服务:用来帮你在请求header中添加CORS,这个“代理商”会帮助你的客户端发送请求,然后接收服务端的返回数据再传送给客户端。与早期使用的chrome插件Allow-control-allow-origin一样,“代理商”会在收到服务端返回的时候,在返回的header中加入Access-Control-Allow-Origin: *


啊乐同学:这种原理是什么?


答:该方法利用了同源策略只作用于浏览器-服务器之间的通信,而同源策略并不会限制服务端与服务端之间的通信


翻了下源码,通过重写XMLHttpRequest.open()


微信截图_20220514173734.png


🌲 拓展阅读:


4.2 http-proxy-middleware


http-proxy-middleware用于后台将请求转发给其它服务器,跟上一节提的原理是一致的,不过它是一个中间件,需要结合express使用文档链接


微信截图_20220514173747.png


无论我们平时在使用webpack中webpack-dev-server配置还是vue-cli中的vue.config.js中的devServer,来配置本地开发接口映射,以此接解决本地开发跨域存在的问题,本质上就是基于http-proxy-middleware中间件 ,通过把后端的API的请求代理到本地服务器上,方便与后台数据调试,解决跨域问题~


配置如下所示:


我们看看 webpack中webpack-dev-server的实现就是基于http-proxy-middleware源码链接




啊轩同学:自己如何搭建一个基于http-proxy-middleware的中间件的代理服务?


可以通过http-proxy-middleware中间件 + Express来实现,如下所示👇


微信截图_20220514173801.png


🌲 拓展阅读:


4.3 Nginx反响代理


前两者介绍的主要是针对本地开发环境,跨域的解决方案。但是一般项目上线如果要解决存在的跨域问题,可以通过nginx作代理


数据交互流程:

  • 数据请求过程:客户端浏览器 -> 反向代理服务器 -> 处理数据的服务器
  • 数据返回过程:处理数据的服务器 -> 反向代理服务器 -> 客户端浏览器


我们可以通过proxy_pass的配置,确保访问的访问的接口与前端应用静态资源访问保持一致,也能解决跨域问题


微信截图_20220514173812.png


更多nginx配置看🌲树酱的Nginx那些事


相关文章
|
6月前
|
前端开发 安全 JavaScript
前端开发中的跨域资源共享(CORS)机制
【2月更文挑战第3天】 在前端开发中,跨域资源共享(CORS)机制是一个重要的安全性问题。本文将介绍CORS的概念、原理和实现方式,并探讨在前端开发中如何处理跨域资源请求,以及如何提高网站的安全性。
|
6月前
|
存储 安全 前端开发
第五章 跨域资源共享(CORS):现代Web开发中的关键机制
第五章 跨域资源共享(CORS):现代Web开发中的关键机制
174 1
|
2月前
|
JSON 前端开发 JavaScript
跨越跨域大山,前端不得不知道的Ajax
该文章介绍了AJAX技术的基本使用方法,包括GET和POST请求的模拟,并探讨了浏览器同源策略及其对跨域请求的影响,同时还提出了JSONP和CORS作为解决跨域问题的方案。
|
3月前
|
前端开发 JavaScript 应用服务中间件
说一说跨域和如何解决
说一说跨域和如何解决
|
3月前
|
前端开发 应用服务中间件 API
"揭秘!面试官必问:你是如何巧妙绕过跨域难题的?前端代理VS服务器端CORS,哪个才是你的秘密武器?"
【8月更文挑战第21天】在软件开发中,尤其前后端分离架构下,跨域资源共享(CORS)是常见的挑战。主要解决方案有两种:一是服务器端配置CORS策略,通过设置响应头控制跨域访问权限,无需改动前端代码,增强安全性;二是前端代理转发,如使用Nginx或Webpack DevServer在开发环境中转发请求绕过同源策略,简化开发流程但不适用于生产环境。生产环境下应采用服务器端CORS策略以确保安全稳定。
52 0
|
6月前
|
Web App开发 JavaScript 前端开发
深入理解前端跨域方法和原理
深入理解前端跨域方法和原理
|
6月前
|
JSON JavaScript 前端开发
跨域的原理及解决方案
同源策略是Web应用程序安全性模型中的重要概念。根据该策略,Web浏览器允许第一个网页中包含的脚本访问第二个网页中的数据,但前提是两个网页具有相同的来源。来源由URI,主机名和端口号的组合定义。此策略可防止一个页面上的恶意脚本通过该页面的DOM(Document Object Model)获得对另一网页上敏感数据的访问。 JSONP 由于同源策略,一般来说位于server1.example.com...
|
JavaScript 安全 前端开发
跨越跨域限制,掌握 Axios 的跨域解决策略
跨域是指访问另外一个域的资源,由于浏览器的同源策略,默认情况下使用 XMLHttpRequest 和 Fetch 请求时是不允许跨域的。跨域的根本原因是浏览器的同源策略,这是由浏览器对 JavaScript 施加的安全限制。
|
JSON 缓存 前端开发
从前后端的角度分析options预检请求——打破前后端联调的理解障碍
options预检请求是干嘛的?options请求一定会在post请求之前发送吗?前端或者后端开发需要手动干预这个预检请求吗?不用文档定义堆砌名词,从前后端角度单独分析,大白话带你了解!
458 0
从前后端的角度分析options预检请求——打破前后端联调的理解障碍
|
前端开发 文件存储 数据安全/隐私保护
【小刘带你玩儿前端】什么是跨域以及如何解决?
现在的web项目,很多都是前后端分离,特别容易出现跨域问题
【小刘带你玩儿前端】什么是跨域以及如何解决?