同源策略是一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互,它能帮助阻隔恶意文档,减少可能被攻击的媒介。
MDN上有详细解释, 如果两个 URL 的协议、端口(如果有指定的话)和主机都相同的话,则这两个 URL 是同源的。 比如:跟URL 的源进行对比,这个源默认端口是80。
浏览器并不是拒绝所有的跨域请求,实际上拒绝的是跨域的读操作。 同源策略控制不同源之间的交互,例如在使用 或 标签时则会受到同源策略的约束。这些交互通常分为三类:
1、跨源写操作(Cross-origin writes)一般是被允许的,如、以及
2、跨源资源嵌入(Cross-origin embedding)一般是被允许的,如 、 标签
3、跨源读操作(Cross-origin reads)一般是不被允许的,如我们的等
浏览器出于安全考虑,对于同源的请求通过,对于不是同源的请求会限制,这就是浏览器的 同源策略,对于不满足浏览器浏览器同源策略出现的开发问题,就是跨域问题。
说得更直白一点,我们通过一个url访问一个页面,这个页面的url叫做页面源,在这个页面中会有很多的请求,比如请求css,js,图片等等,还有使用xhr或者fetch去请求一些动态数据,这些请求的都url地址叫做目标源,当页面源和目标源的协议、主机、端口不一致,就会出现跨域问题。本文重点关注使用AJAX发请求遇到的跨域问题。
注意:当跨域请求时,浏览器同样会发出请求,服务器也同样会响应,但是当浏览器接受到服务器的响应时会去校验,校验不通过,就会出现跨域报错。
比如在百度页面里请求淘宝,跨域报错了,但是淘宝服务器是成功响应了的。


是W3C的标准,是AJAX跨域请求的根本解决方式。在 Node代理 和 Nginx反向代理中一些情况也离不开CORS
MDN上面 跨源资源共享(CORS)和阮一峰老师的 跨域资源共享 CORS 详解 做了详细的解释 ,CORS是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。它使浏览器通过对跨域请求的校验。使用这种方法,关键在于服务器。
CORS把请求分成两种:简单请求和预检请求。
满足下面所有条件的是简单请求:
1、请求方法是:
3、请求头信息不超过以下几个字段 , 不要去改其他请求头字段;
2、Content-type类型只能是: , ,;
4、如果请求是使用 对象发出的,在返回的 对象属性上没有注册任何事件监听器;也就是说,给定一个 实例 ,没有调用 ,以监听该上传请求。
5、请求中没有使用 对象。
简单请求以外的就是非简单请求。
例如:
在淘宝页面请求百度页面,使用put方法,非简单请求,method:put + preflight

在淘宝页面请求百度页面,修改请求头,非简单请求,method:get + preflight

在淘宝页面请求百度页面,修改content-type,非简单请求,method:post + preflight

浏览器发现跨域是个简单请求,会带上一个请求头,字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。


要解决跨域,服务器只需要设置对应到响应头:
必须设置的字段,可以设置,允许所有源访问,或者设置明确允许的源,但是就不能发送cookie了,需要明确设置为允许通过的源
在跨域请求下,浏览器是不带 Cookie 的。但是客户端可以通过设置 来进行传递 Cookie
讯享网
服务端设置
讯享网
服务端实现测试:
讯享网
把html用本地或者live server方式打开,然后请求koa起的服务器地址,会出现跨域问题,不同源

给响应头设置Access-Control-Allow-Origin:* 就请求成功了,
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求():
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的Ajax请求,否则就报错。
"预检"请求用的请求方法是,预检请求中,请求头字段:
,必带的字段;
,必带的字段,用来列出浏览器的CORS请求用到的HTTP方法;
:是一个逗号分隔的字符串,实际请求将携带自定义请求头字段
例如:
put请求,请求头中没有

get请求,header中加自定义字段,请求头中有、:

put请求,修改content-type,请求头中有、:




响应头字段:
,必须设置的字段,允许通过预检的源
也是必须设置的字段,服务器允许请求头头中携带字段
,服务器将接受后续的实际请求方法
减少预请求的次数,需要包含在预请求的响应头中,指定在该时间内预请求验证有效,不必每次都进行预请求,它的单位是 。如 ,即有效期为1天
讯享网
Node原生实现:
koa中间件实现
讯享网
出现的早,兼容性好(兼容低版本IE)。是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案。
缺点是只支持 请求,不支持 请求。
跨源资源嵌入(Cross-origin embedding)一般是被允许的,动态创建 脚本标签,通过跨域脚本嵌入不受同源策略限制的方法实现请求第三方服务器数据内容。除了适用于 脚本标签,HTML 中包含 和 属性的标签均不受同源策略限制。
所以JSONP的做法是, 把前端定义好的一个函数名,放在src路径上,当作参数传递给服务端,然后服务端拿到这个函数名, 拼成一个函数调用字符串返回前端,并把响应结果当作参数传递给前端:
服务端实现
讯享网


和 都需要服务器的配合,需要服务器设置响应头,需要服务器返回一段函数调用的Js代码,使用Node代理就不需要后端的配合。

使用koa起一个目标服务器
客户端请求,使用 live server或者本地打开
讯享网
此时必然出现跨域问题

再使用起一个代理服务器,使用一个中间件 http-proxy-middleware,当我们在webpack中,配置proxy时,底层也是使用的

再修改一下客户端请求地址为代理服务器地址
讯享网
然后请求成功


我们平时开发中使用webpack和vite等构建工具,用命令 ,开启一个本地服务器,然后把我们在文件夹的源代码部署在本地服务器。在浏览器中打开项目,页面源和目标源都是代理服务器地址。
例如:
客户端代码,目标服务器代码都同上,将index.html放到public文件夹
修改一下代理服务器代码

什么是正向代理?Node代理就是正向代理,我们访问代理服务器地址,目标服务器不知道真实的客户端()
反向代理就是客户端什么都不用配置,甚至都不知道自己的请求被代理了,代理,以为自己访问的就是真实的服务器()。
下载 nginx,运行后,在地址栏输入localhost,默认80端口, 可以看到启动成功的页面

打开下载的文件,可以看到
讯享网
启动一个koa目标服务器
配置nginx,监听80端口,代理路径 到启动的目标服务器
讯享网
客户端发送请求,本地打开index.html
没有设置CORS,出现跨域问题

修改一下nginx配置,设置CORS,同样,需要根据简单和非简单请求设置不同的响应头
讯享网
请求成功

修改index.html请求路径
把上面的index.html文件放到文件夹中,把文件夹放到跟 同一级目录,

修改nginx配置,
讯享网


跨域资源共享 CORS 详解
JSONP 跨域原理及实现
JavaScript Guidebook
深入理解 http 反向代理(nginx)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/152520.html