跨域请求底层原理以及解决方案

在大学的时候与组员们做项目联调,他的前端,请求不了我后端的数据,于是这是与跨域的第一次偶遇。当时青春懵懂,随便百度了一下,在Controller加了个CrossOrigin解决了问题就算了,具体原因,咱也没深究。
直到工作了,遇到越来越多问题,也越来越好奇,才去主动了解一些之前没机会了解的东西,包括老朋友跨域…
跨域出现的原因:

(1)协议不同。(http和https)
(2)域名不同。(test和tests ,或者是直接请求IP的不同)
(3)端口号不同。(8080和8081)
以上三种条件都相同,就是同域,可以正常读写域内资源,有一个条件不同,请求方与响应方都属于跨域,无法进行资源访问。
这就叫做同源策略。

追问一:为什么要搞这些同源策略?

它这么烦搞出这些规则,是为了防止CSRF攻击和XSS攻击。CSRF攻击和XSS攻击。毕竟访问一个网站,进行一些注入型攻击后就能自由访问本机的文件,那是非常可怕的一件事情,例如我在加载的script代码中插入:let xhr = new XMLHttpRequest(); xhr.open('get','./XXX/XXX/XXX,true);假设那个文件存在的话,就会被读取,然后再通过一些回调接口返回文件内容。

不是所有浏览器都会有同源策略,在我们做实验中,谷歌默认是不支持跨域的,IE支持,火狐支持。为什么会这样?

火狐浏览器为了防止跨域带来的诸多不便,所以默认支持跨域请求。谷歌则是为了更安全考虑,不允许网站页面直接读取本地文件,这都是浏览器自己做的安全机制限制的。

做过页面读取本地文件的并且用的谷歌,都会发现就连自己本地页面访问本地文件都会出现跨域,百思不得其解?

反正记住跨域就是因为那三点,要么协议不同了,域名不同,或者端口号不同。而读取本地的txt文件,就是因为访问计算机文件默认使用的是file协议。

file协议:本地文件传输协议。主要用来访问本地计算机的文件。用法:file:///XX/XX/XX(路径)我们可以在资源管理器或者‘我的电脑‘上的路径栏,或者浏览器,输入file:///C:/XX/XXX/XX.txt就可以了。
http协议:超文本传输协议,基于TCP/IP协议的,用来从网络传输文本的传输协议。
File和Http协议
协议的不同,所以就导致了跨域。

如何解决跨域问题?

在Spring中直接加@ CrossOrigin就可以。
或者发起JSONP方式,也不会出现跨域问题。

@CrossOrigin 为什么能解决跨域问题?

点击进去源码查看,可以发现添加了注释后,它默认是对所有请求源头开放
在这里插入图片描述
而被加了这个注解的类,在MappingHandler将Controller class 方法和请求路径进行绑定映射的时候,就会对这个class特殊照顾,判断是否发生了跨域请求,假如有,那么就在这个响应头里添加Access-Control-Allow-Origin信息。使得这个请求支持跨域。

JSONP为什么能解决跨域?

它是利用了HTML带有src属性的标签,例如<script ,< img , 之类,它们可以载入任何地方的资源,并且不受同源策略限制。但是它只能默认get请求,无法发起post和put等。
所以,当使用JSONP发起请求,它会默认临时构造一个<script 在请求路径后面还会有回调地址,例如< s c r i p t> type=“text/javascript” src=“https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction”></ s c ri p t 这样来实现文件的动态加载。
虽然AJAX常用 jsonp来解决跨域,但是两种请求方式是完全不一样的,当ajax的dataType = json时候,它默认http读取加载文件,当是jsonp的时候,它选择的是构造临时的 <s c ri p t src ='XX/XX/XX/callback=XX/XX/XX>这种方式来动态获取。默认的callback回调就是ajax那个success function(){}

猜你喜欢

转载自blog.csdn.net/whiteBearClimb/article/details/107313025
今日推荐