本文目录一览:
CORS过程的介绍以及跨域问题
参考文章:
说到跨域问题,我们最常见的就是在我们向服务器发起请求的时候会遇到。比如说如下情况
假设我们正在访问 的站点,当我们点击按钮,向 发送请求,获取网站上的一些用户信息。这个时候从结果上是完美的。原因是,根据 同源策略 ,我们发起请求的 域名 , 端口 , 协议 均是一至的。浏览器并不会产生跨域报错。-cors跨域php
而如果,以上提到的三点其中一点不满足的站点,再向服务器发起请求,那么这个时候就会触发跨域报错。如下图
而以上两种情况出现的原因,其实就是我们今天要介绍的内容。
首先我们先来介绍一下同源策略
浏览器网络请求的时候,有一个 同源策略 的机制,即默认情况下,使用API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源。也就是我们上面提到的,必须要求域名,端口,协议都要一至。请求才能发送成功。而只要其中一点不一致,那么该请求也算是跨域的。-cors跨域php
所以我们同样可以看得出来。同源策略会限制以下三种行为:
说了这么多其实,我们可以看出同源策略的作用其实就是为了保证用户的信息安全。打个比方,如果没有同源策略,那么当你在不小心的情况下,点击了网页的钓鱼网站。然后恶意的网站很容易就能利用重定向把你带到一个iframe 的 攻击网站,这个iframe会自动加载银行网站,并通过Cookie登录你的账号。然后操作你的DOM,进行一系列的危险操作。-cors跨域php
而我们当然不希望这种情况发生,这个时候同源策略就起到有效的保护作用。因为它确保了我们只能访问同一站点的资源
好了,接下来要说的就是CORS了。
浏览器出于安全的考虑,会限制 从脚本内发起 的跨域HTTP请求。(注意是脚本内)例如XHR 和 Fetch 就遵循同源策略。这意味着使用 API 的Web应用程序只能从加载应用程序的同一个域请求HTTP资源。-cors跨域php
在日常的开发中,我们很多时候都会跨域去请求别的站点的资源。而这个时候我们为了解决跨域的问题就要利用CORS机制。
CORS(Cross-Origin Resource Sharing),即 跨域资源共享 。如字面意思,CORS机制的存在就是为了让我们在保证安全的前提下,实现访问不同域下的资源,这算是放宽的政策。-cors跨域php
浏览器可以利用CORS机制,放行一些符合规范的跨域访问,阻止不符合规范的跨域访问。下面我我们就来介绍一下浏览器内部是如何实现的。
Web程序发出跨域请求后,浏览器会 自动 向我们的HTTP header添加一个额外的字段 Origin 。 Origin 标记了请求的站点来源:
为了使浏览器允许访问跨域资源,服务器返回的 response 还需要加一些响应头字段,这些字段可以 显式 的表明此服务器是否允许跨域请求。
作为服务端人员,我们为了允许符合规则的跨域请求。我们可以通过在HTTP的响应中添加响应字段 Access-Control-* 来表明是否允许跨域请求。根据这些CORS响应头字段,浏览器可以允许一些被同源策略限制的跨域响应-cors跨域php
虽然有好几个CORS的字段,但是有一个必须要加的字段是 Acess-Control-Allow 。这个头字段的值指定了哪些站点被允许跨域访问资源的。
现在这个字段会被添加到服务端的响应报文中,然后返回给客户端。然后这个时候客户端再向服务端发起跨域请求,同源策略将不会再限制 站点返回的资源。
报文如下:
而相反,如果对比 Access-Control-Allow-Origin 和 Origin 的值不一致的时候,浏览器会抛出一个 CORS Error的报错信息。
除了 Access-Control-Allow-Origin 字段头之外,开发人员还可以通过其他字段对请求作出限制。比如说 Access-Control-Allow-Methods 该字段用来指明跨域请求所允许的 HTTP 方法。-cors跨域php
如上图中,只有请求方法为 GET , POST 或 PUT 方法被允许跨域访问资源。其他的HTTP方法,例如 PATCH 和 DELETE 都会产生预检。
这里就引申出一些别的内容,比如说 预检
什么是预检呢?
到这里,CORS和跨域的关系基本就说清楚了。下面我们再说一点补充
XHR 或 Fetch 与 CORS的一个有趣的特性是,我们可以基于 Cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 XHR 或 Fetch 请求,浏览器 不会 发送身份凭证信息。-cors跨域php
尽管 CORS 默认 情况下不发送身份凭证,但我们仍然可以通过添加 Access-Control-Allow-Credentials CORS响应头来更改它
如果要在跨域请求中包含 cookie 和其他授权信息,我们需要做一下操作:
做到了上面几点之后,就能在跨域请求中携带身份凭证了。
以上就是全部内容了
补充参考:
【http】什么是cors跨域
前端开发中,常常需要进行跨域请求。既然提到跨域,首先我们的知道什么是“同源策略”。
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
如果协议,端口(如果指定了一个)和域名对于两个页面是相同的,则两个页面具有相同的源。
同一个源内,资源的访问是很自由的。就跟在自己家中,想开冰箱开冰箱,想干啥干啥。如果你想访问不同源的资源,可就没那么自由了,这就是跨域。
关于跨域,常用的JSONP应该都知道。JSONP的原理是什么呢?我们来看看大神贺师俊的解释:
很简单,就是利用script标签没有跨域限制的“漏洞”(历史遗迹啊)来达到与第三方通讯的目的。当需要通讯时,本站脚本创建一个script元素,地址指向第三方的API网址,并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。 第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),这样浏览器会调用callback函数,并传递解析后json对象作为参数。本站脚本可在callback函数里处理所传入的数据。 -cors跨域php
可以知道JSONP就是个bug般的存在啊,如果你是一个有洁癖的程序员回想说:这不合理,这部干净。因此我们引出cors。
那么,什么是cors呢?
我们来看看互动百科的解释:
CORS(跨来源资源共享)是一份浏览器技术的规范,提供了Web服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,是JSONP模式的现代版。
维基百科的解释(手动谷歌):
Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served. -cors跨域php
这样看来,其实嘛,cors就是一个规范,机制,基于这个规范,不同源之间才可以请求资源。相当于一个江湖规矩,大家都按规矩来嘛不是?不讲规矩?信不信小拳拳捶你。
所以呢,要想使用cors跨域访问,你就得讲规矩。下面我们来看看有哪些规矩。
跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:
cors中有个术语叫 “简单请求” ,若请求满足所有下述条件,则该请求可视为“简单请求”:
使用下列方法之一:
之所以区分简单请求,是因为cors需要处理一些“非简单请求”,这种特殊处理叫做“预检请求”。大人物来了,总要提前准备准备吧,封路啥的blabla。
预检请求的作用是 提前获知服务器是否允许该实际请求 。“预检请求”的使用,可以 避免跨域请求对服务器的用户数据产生未预期的影响 。
一张图可以清晰看到提前发送预检请求的cors请求
Request Headers:
Response Header:
cors在koa中的使用:
相关链接:
跨域问题解决方法
跨域?他是浏览器的 同源策略 造成的,是浏览器对javascript施加的安全限制。所谓同源是指:域名、协议、端口均相同。
解决
原理:利用标签具有可跨域的特性,可实现跨域访问接口,需要后端的支持。
服务器在收到请求后,解析参数,计算返还数据,输出messagetow(data)字符串。
缺点:只能发送get请求,无法访问服务器的响应文本(单向请求),即只能获取数据不能改数据。
通过ajax请求不同域的实现,底层不是靠XmlHttpRequest而是script,所以不要被这个方法给迷惑了。
在ajax请求中类型如果是type是get post,其实内部都只会用get,因为其跨域的原理就是用的动态加载script的src,所以我们只能把参数通过url的方式传递
其实jquery内部会转化成
然后动态加载;action=aaron"
;action=aaron"script type="text/javascript" src=" "/script
;action=aaron"
;action=aaron"
Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,确保安全的跨域数据传输。现代浏览器使用CORS在API容器如XMLHttpRequest来减少HTTP请求的风险来源。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。服务器一般需要增加如下响应头的一种或几种:-cors跨域php
跨域请求默认不会携带Cookie信息,如果需要携带,请配置下述参数:
window.name通过在iframe(一般动态创建i)中加载跨域HTML文件来起作用。然后,HTML文件将传递给请求者的字符串内容赋值给window.name。然后,请求者可以检索window.name值作为响应。-cors跨域php
iframe标签的跨域能力;
window.name属性值在文档刷新后依旧存在的能力(且最大允许2M左右)。
每个iframe都有包裹它的window,而这个window是top window的子窗口。 contentWindow 属性返回iframe元素的Window对象。你可以使用这个Window对象来访问iframe的文档及其内部DOM。-cors跨域php
HTML5新特性,可以用来向其他所有的 window 对象发送消息。需要注意的是我们必须要保证所有的脚本执行完才发送 MessageEvent,如果在函数执行的过程中调用了它,就会让后面的函数超时无法执行。-cors跨域php
前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域,所以只能跨子域
在 根域 范围内,允许把domain属性的值设置为它的上一级域。例如,在”aaa.xxx.com”域内,可以把domain设置为 “xxx.com” 但不能设置为 “xxx.org” 或者”com”。-cors跨域php
现在存在两个域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的页面,由于其document.name不一致,无法在aaa下操作bbb的js。可以在aaa和bbb下通过js将document.name = 'xxx.com';设置一致,来达到互相访问的作用。-cors跨域php
WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很棒的实现。相关文章,请查看: WebSocket 、 WebSocket-SockJS -cors跨域php
**需要注意:**WebSocket对象不支持DOM 2级事件侦听器,必须使用DOM 0级语法分别定义各个事件。
同源策略是针对浏览器端进行的限制,可以通过服务器端来解决该问题,例如nginx
DomainA客户端(浏览器) == DomainA服务器 == DomainB服务器 == DomainA客户端(浏览器)
使用CORS解决跨域问题
跨域是指跨域名的访问,以下情况都属于跨域:
如果 域名和端口都相同,但是请求路径不同 ,不属于跨域,如:
跨域不一定会有跨域问题。
因为跨域问题是浏览器对于ajax请求的一种安全限制: 一个页面发起的ajax请求,只能是于当前页同域名的路径 ,这能有效的阻止跨站攻击。
因此: 跨域问题 是针对ajax的一种限制 。
但是这却给我们的开发带来了不变,而且在实际生成环境中,肯定会有很多台服务器之间交互,地址和端口都可能不同,怎么办?
目前比较常用的跨域解决方案有3种:
我们这里会采用cors的跨域方案。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了AJAX只能 同源 使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
浏览器会将ajax请求分为两类,其处理方案略有差异:简单请求、特殊请求。
只要同时满足以下两大条件,就属于简单请求。:
(1) 请求方法是以下三种方法之一:
(2)HTTP的头信息不超出以下几种字段:
当浏览器发现发现的ajax请求是简单请求时,会在请求头中携带一个字段: Origin .
Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。
如果服务器允许跨域,需要在返回的响应头中携带下面信息:
注意:
如果跨域请求要想操作cookie,需要满足3个条件:
不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT。
特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。
一个“预检”请求的样板:
与简单请求相比,除了Origin以外,多了两个头:
服务的收到预检请求,如果许可跨域,会发出响应:
除了 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 以外,这里又额外多出3个头:
如果浏览器得到上述响应,则认定为可以跨域,后续就跟简单请求的处理是一样的了。
虽然原理比较复杂,但是前面说过:
事实上,SpringMVC已经帮我们写好了CORS的跨域过滤器:CorsFilter ,内部已经实现了刚才所讲的判定逻辑,我们直接用就好了。
在 Application 下编写一个配置类,并且注册CorsFilter:
结构:
放到Application下即可。
4.5.4.重启测试:
访问正常:
thinkphp6解决 CORS 跨域
1,在app/middleware.php中添加
中间件,这样就改成了
*是不安全的,可以在config/cookie.php配置cookie 有效域名的domain
如果接口请求发送了token,会提示Access-Control-Allow-Headers这个问题,tp6默认是这样
可以在'Access-Control-Allow-Headers' 这一样加上XXX-token,
我在搞这个时还遇见post请求变成get
把method改成了type