首页 > 其他分享 >跨域问题是怎样造成的?

跨域问题是怎样造成的?

时间:2023-04-28 17:12:29浏览次数:47  
标签:浏览器 请求 造成 同源 HTTP 怎样 服务端 跨域

参考: https://www.cnblogs.com/sxw123/p/15018999.html

跨域问题的由来

相信很多人都或多或少了解过跨域问题,尤其在现如今前后端分离大行其道的时候。

你在本地开发一个前端项目,这个项目是通过 node 运行的,端口是9528,而服务端是通过 spring boot 提供的,端口号是7001。

当你调用一个服务端接口时,很可能得到类似下面这样的一个错误:

img

然后你在发送请求的地方debug,在出现异常的地方你将得到这样的结果:

img

异常对象很诡异,返回的 response 是 undefined 的,并且 message 消息中只有一个"Network Error"。

看到这里你应该要知道,你遇到跨域问题了。

但是你需要明确的一点是,这个请求已经发出去了,服务端也接收到并处理了,但是返回的响应结果不是浏览器想要的结果,所以浏览器将这个响应的结果给拦截了,这就是为什么你看到的response是undefined。

浏览器的同源策略

那浏览器为什么会将服务端返回的结果拦截掉呢?

这就需要我们了解浏览器基于安全方面的考虑,而引入的 同源策略(same-origin policy) 了。

早在1995年,Netscape 公司就在浏览器中引入了“同源策略”。

最初的 “同源策略”,主要是限制Cookie的访问,A网页设置的 Cookie,B网页无法访问,除非B网页和A网页是“同源”的。

那么怎么确定两个网页是不是“同源”呢,所谓“同源”就是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

img

没有同源策略的保护

那么为什么要做这个同源的限制呢?因为如果没有同源策略的保护,浏览器将没有任何安全可言。

老李是一个钓鱼爱好者,经常在 我要买(51mai.com) 的网站上买各种钓鱼的工具,并且通过 银行(yinhang.com) 以账号密码的方式直接支付。

这天老李又在 51mai.com 上买了一根鱼竿,输入银行账号密码支付成功后,在支付成功页看到一个叫 钓鱼(diaoyu.com) 的网站投放的一个"免费领取鱼饵"的广告。

老李什么都没想就点击了这个广告,跳转到了钓鱼的网站,殊不知这真是一个 “钓鱼” 网站,老李银行账户里面钱全部被转走了。

img

以上就是老李的钱被盗走的过程:

1.老李购买鱼竿,并登录了银行的网站输入账号密码进行了支付,浏览器在本地缓存了银行的Cookie

2.老李点击钓鱼网站,钓鱼网站使用老李登录银行之后的Cookie,伪造成自己是老李进行了转账操作。

这个过程就是著名的CSRF(Cross Site Request Forgery),跨站请求伪造,正是由于可能存在的伪造请求,导致了浏览器的不安全。

那么如何防止CSRF攻击呢,可以参考这篇文章:如何防止CSRF攻击?

同源策略限制哪些行为

上面说了 **同源策略 **是一个安全机制,他本质是限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互,这是一个用于隔离潜在恶意文件的重要安全机制。

随着互联网的发展,"同源策略"越来越严格,不仅限于Cookie的读取。目前,如果非同源,共有三种行为受到限制。

img

虽然这些限制是必要的,但是有时很不方便,合理的用途也会受到影响,所以为了能够获取非“同源”的资源,就有了跨域资源共享。

跨域资源共享

看到这里你应该明白,为什么文章开头的请求会被拦截了,原因就是请求的源和服务端的源不是“同源”,而服务端又没有设置允许的跨域资源共享,所以请求的响应被浏览器给拦截掉了。

CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross Origin Resource Sharing),它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了只能发送同源请求的限制。

CORS实现机制

那跨域资源共享机制是怎样实现的呢?

当一个资源(origin)通过脚本向另一个资源(host)发起请求,而被请求的资源(host)和请求源(origin)是不同的源时(协议、域名、端口不全部相同),浏览器就会发起一个 跨域 HTTP 请求 ,并且浏览器会自动将当前资源的域添加在请求头中一个叫 Origin 的 Header 中。

当然了,有三个标签本身就是允许跨域加载资源的:

img

比如某个网站的首页 http://domain-a.com/index.html 通过 来加载其他域上的图片,除此之外还有诸如通过 CDN 节点引入css和js文件的方式。

出于安全原因,浏览器限制从脚本内发起的跨域 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。也就是说使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文中包含了正确 CORS 响应头。

通过在响应报文中设置额外的 HTTP 响应头来告诉浏览器,运行在某个 origin 上的 Web 应用被准许访问来自不同源服务器上的资源,此时浏览器就不会将该响应拦截掉了。

那这些额外的 HTTP 响应头是什么呢?

img

其中只有 Access-Control-Allow-Origin 是必须的,该响应头的值可以是请求的 Origin 的值,也可以是 * ,表示服务端接收所有来源的请求。

当浏览器发起 CORS 请求时,默认只能获得6个响应头的值:

Cache-Control`、`Content-Language`、`Content-Type`、`Expires`、`Last-Modified`、`Pragma

如果还需要返回其他的响应头给前端,则可以通过在 Access-Control-Expose-Headers 中指定。

CORS的两种请求类型

CORS有两种类型的请求,分别是:简单请求(simple request)和非简单请求(not-so-simple request)

只要同时满足以下两大条件,就属于简单请求。

img

凡是不同时满足上面两个条件,就属于非简单请求,浏览器对这两种请求的处理,是不一样的。

为什么会有两种不同类型的请求呢?

CORS 规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。

服务器确认允许之后,浏览器才能发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关的数据)。

非简单请求就要求浏览器先发送一个预检请求,预检通过后再发送实际的请求。

标签:浏览器,请求,造成,同源,HTTP,怎样,服务端,跨域
From: https://www.cnblogs.com/chenxdnote/p/17362680.html

相关文章

  • 怎样制作从负数开始的序列号
    在使用条码标签软件时,有的用户除了批量制作条码或二维码,也会制作一些序列号。我们通常用到的序列号都是0、1、……、8、9这种的,但是如果需要的序列号是从负数开始,像“-10、-9、-8、……0、1、2、3…”这种的(如下图),要怎么实现呢?下面我们演示一下在条码标签软件中制作从负数开始的序......
  • CDN加速WordPress触发CORS导致跨域加载失败
    这两天折腾CDN加速来提升自己博客的访问速度,用的阿里云CDN加速方案;使用的时候发现一个问题,部分资源CDN加速失败,原因是触发了CORS,因为CDN加速网址与博客网址不一致引发的跨域请求不成功;从报错中发现Off与Tff字体加载报错:(index):1AccesstoFontat'http://cdn.5yun.org/wp-conte......
  • phpstudy配置nginx跨域请问
    add_headerAccess-Control-Allow-Origin*; add_headerAccess-Control-Allow-Methods'GET,POST,OPTIONS'; add_headerAccess-Control-Allow-Headers'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Cont......
  • js -- 跨域问题
    js--跨域问题  前言出于浏览器同源策略的影响,浏览器会阻止一个域的js脚本和另一个域的内容进行交互,因此产生了跨域问题,该问题也经常在面试和开发中遇到,本文来总结一下相关知识点。正文1、什么是同源策略因为浏览器出于安全考虑,存在同源策略,就是说如果......
  • 发布Flash跨域策略,CORS跨域资源共享漏洞,设置访问白名单
    1      问题描述:跨域策略文件配置问题:<allow-access-fromdomain="*"/>,允许从任何域进行访问 2      解决方案:找到对应的文件,正确配置白名单,配置样例如下: ......
  • 怎样将项目上传到gitee中
    怎样将本地项目上传到gitee方法一1、首先在gitee上新建仓库2、在本地磁盘新建一个文件夹,上传代码。2.1、在本地新建upload文件夹2.2、在该文件夹中打开gitBash2.3、输入命令1:gitinit2.4、使用命令添加远程仓库2.5、输入命令2:gitpulloriginmaster2.6、将要上传的文件添加到up......
  • NET CORE 跨域问题
    在StartUp类里面配置如下代码即可解决跨域问题publicvoidConfigureServices(IServiceCollectionservices){services.AddCors(p=>p.AddPolicy("corsapp",builder=>{builder.WithOrigins("*").AllowAnyMethod().Allo......
  • 前端跨域解决方案——CORS
    CORS(跨来源资源共享)是一种用于解决跨域问题的方案。CORS(跨来源资源共享)是一种安全机制,用于在浏览器和服务器之间传递数据时,限制来自不同域名的请求。在前端开发中,当通过XMLHttpRequest(XHR)或FetchAPI发送跨域请求时,如果服务器没有正确配置CORS,浏览器会阻止该请求,从而导致请求......
  • 不允许你还不会秒想到怎样精准判断数据类型!!!
    提到数据类型,会想到基本数据类型和引用数据类型,那么你怎么判断?一、typeof【语法:typeof+变量名】        大多数人首先想到的一定是这个,但注意了,typeof判断基本数据类型很好用,但是有一个特例,(Null)打印出来也和复杂数据类型一样显示object,除此之外,需要注意:用typeof检测构造函......
  • PostgreSQL插件那么多,怎样管理最高效?
    摘要:华为云RDSforPostgreSQL通过插件管理功能,很好地解决了PostgreSQL版本与插件耦合的问题,帮助用户更直观、更快速地安装管理数据库插件。本文分享自华为云社区《PostgreSQL插件那么多,怎样管理最高效?》,作者:GaussDB数据库。云服务环境下,如何让客户更方便地在各个PostgreSQL的......