当前位置:网站首页 > 编程语言 > 正文

跨域是什么错误码(跨域请求是什么)



跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。
同源策略:是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。所谓的同源,指的是协议、域名、端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。

  • Cookie , LocalStorage ,IndexedDB等存储性内容。
  • DOM节点
  • AJAX请求发送后,非同源会被浏览器拦截。
    但是有三个标签是允许跨域加载资源:
 

反向代理:隐藏真实的服务器端

正向代理:隐藏真实的客户端

介绍

Nginx 通过反向代理的方式保证当前域,能获取到静态资源和接口,不关心是怎么获取的。
Nginx 从入门到实践
nginx反向代理和负载均衡策略实战案例

配置 Nginx

 

实现

前端代码

 

后端代码

 

CORS(cross-origin resource sharing),跨源资源共享(一般俗称『跨域请求』),跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器「不同的域、协议或端口」请求一个资源时,资源会发起一个「跨域 HTTP 请求。 
MDN 上的介绍 (developer.mozilla.org/en-US/docs/…
而在 cors 中会有 简单请求 和 预检请求(preflighted requests)的概念。
浏览器支持情况:当你使用 IE<=9, Opera<12, or Firefox<3.5 或者更加老的浏览器,这个时候请使用 JSONP 。

简单请求

不会触发 CORS 预检请求。这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。
若请求满足所有下述条件,则该请求可视为“简单请求”:

  • HTTP 方法只能是 GET、HEAD 或 POST;
  • HTTP 头只能是 Accept/Accept-Language/Conent-Language/Content-Type/DPR/Downlink/Save-Data/Viewport-Width/Width;
  • Content-Type 头只能是 text/plain、multipart/form-data 或 application/x-www-form-urlencoded。
  • 请求中的任意  对象均没有注册任何事件监听器; 对象可以使用 属性访问。
  • 请求中没有使用 对象。

非简单请求

除以上情况外的。

看上去很是复杂。那么怎么理解这些限制呢?
其实,简单请求就是普通 HTML Form 在不依赖脚本的情况下可以发出的请求,比如表单的 method 如果指定为 POST ,可以用 enctype 属性指定用什么方式对表单内容进行编码,合法的值就是前述这三种。
非简单请求就是普通 HTML Form 无法实现的请求。比如 PUT 方法、需要其他的内容编码方式、自定义头之类的。

对于服务器来说,第一,许多服务器压根没打算给跨源用。当然你不给 CORS 响应头,浏览器也不会使用响应结果,但是请求本身可能已经造成了后果。所以最好是默认禁止跨源请求。
第二,要回答某个请求是否接受跨源,可能涉及额外的计算逻辑。这个逻辑可能很简单,比如一律放行。也可能比较复杂,结果可能取决于哪个资源哪种操作来自哪个 origin。对浏览器来说,就是某个资源是否允许跨源这么简单;对服务器来说,计算成本却可大可小。所以我们希望最好不用每次请求都让服务器劳神计算。
CORS-preflight 就是这样一种机制,浏览器先单独请求一次,询问服务器某个资源是否可以跨源,如果不允许的话就不发实际的请求。注意先许可再请求等于默认禁止了跨源请求。如果允许的话,浏览器会记住,然后发实际请求,且之后每次就都直接请求而不用再询问服务器否可以跨源了。于是,服务器想支持跨源,就只要针对 preflight 进行跨源许可计算。本身真正的响应代码则完全不管这个事情。并且因为 preflight 是许可式的,也就是说如果服务器不打算接受跨源,什么事情都不用做。
但是这机制只能限于非简单请求。在处理简单请求的时候,如果服务器不打算接受跨源请求,不能依赖 CORS-preflight 机制。因为不通过 CORS,普通表单也能发起简单请求,所以默认禁止跨源是做不到的。
既然如此,简单请求发 preflight 就没有意义了,就算发了服务器也省不了后续每次的计算,反而在一开始多了一次 preflight。
有些人把简单请求不需要 preflight 理解为『向下兼容』。这也不能说错。但严格来说,并不是『为了向下兼容』而不能发。理论上浏览器可以区别对待表单请求和非表单请求 —— 对传统的跨源表单提交不发 preflight,从而保持兼容,只对非表单跨源请求发 preflight。
但这样做并没有什么好处,反而把事情搞复杂了。比如本来你可以直接用脚本发跨源普通请求,尽管(在服务器默认没有跨源处理的情况下)你无法得到响应结果,但是你的需求可能只是发送无需返回,比如打个日志。但现在如果服务器不理解 preflight 你就干不了这个事情了。
而且如果真的这样做,服务器就变成了默认允许跨源表单,如果想控制跨源,还是得(跟原本一样)直接在响应处理中执行跨源计算逻辑;另一方面服务器又需要增加对 preflight 请求的响应支持,执行类似的跨源计算逻辑以控制来自非表单的相同跨源请求。服务器通常没有区分表单/非表单差异的需求,这样搞纯粹是折腾服务器端工程师。
所以简单请求不发 preflight 不是因为不能兼容,而是因为兼容的前提下发 preflight 对绝大多数服务器应用来说没有意义,反而把问题搞复杂了。

Node 中的解决方案

原生方式

我们来看下后端部分的解决方案。 中 的解决代码.

 

第三方中间件

为了方便也可以直接使用中间件

 

关于 cors 的 cookie 问题

想要传递 需要满足 3 个条件
1.web 请求设置
这里默认情况下在跨域请求,浏览器是不带 cookie 的。但是我们可以通过设置 来进行传递 .

 

2. 为
3.为非
这里请求的方式,在 中是能看到返回值的,但是只要不满足以上其一,浏览器会报错,获取不到返回值。

image.png

 

image.png

 

image.png

前端示例

分别演示一下前端部分 和

简单请求
 

非简单请求

这里我们加入了一个非集合内的 头 来达到非简单请求的目的。

 

image.png

小结

代理的思路为,利用服务端请求不会跨域的特性,让接口和当前站点同域。
代理前
image.png
这样,所有的资源以及请求都在一个域名下了。

cli 工具中的代理

1) Webpack (4.x)

在中可以配置来快速获得接口代理的能力。

 

使用自己的代理工具

cors-anywhere
服务端:

 

前端代码:

 

效果展示:
image.png

charles

介绍

这是一个测试、开发的神器。介绍与使用
利用 charles 进行跨域,本质就是请求的拦截与代理。
在 中设置代理

前端代码
 

后端代码
 

效果

访问 http://localhost:8000/charles

主要就是利用了 标签没有跨域限制的这个特性来完成的。

使用限制

仅支持 GET 方法,如果想使用完整的 REST 接口,请使用 CORS 或者其他代理方式。

流程解析

1.前端定义解析函数(例如 jsonpCallback=function(){....})
2.通过 params 形式包装请求参数,并且声明执行函数(例如 cb=jsonpCallback)
3.后端获取前端声明的执行函数(jsonpCallback),并以带上参数并调用执行函数的方式传递给前端。

使用示例

后端实现

 

普通 js 示例

 

JQuery Ajax 示例

 

原理解析

 

我们稍稍改造一下,外链的形式。

 

我们再改造一下,我们把这个外链的 js 就当做是一个动态的接口,因为本身资源和接口一样,是一个请求,也包含各种参数,也可以动态化返回。

 

你仔细品,细细品,是不是 jsonp 有的优势就是 script 加载 js 的优势,加载的方式只不过换了一种说法。这也告诉我们一个道理,很多东西并没有那么神奇,是在你所学的知识范围内。就好比,桃树和柳树,如果你把他们当成很大跨度的东西去记忆理解,那么世上这么多树,你真的要累死了,你把他们都当成是树,哦吼?你会突然发现,你对世界上所有的树都有所了解,他们都会长叶子,光合作用....当然也有个例,但是你只需要去记忆这些细微的差别,抓住主干。。。嗯,反正就这么个道理。

WebSocket 规范定义了一种 API,可在网络浏览器和服务器之间建立“套接字”连接。简单地说:客户端和服务器之间存在持久的连接,而且双方都可以随时开始发送数据。详细教程可以看 www.html5rocks.com/zh/tutorial…
这种方式本质没有使用了 HTTP 的响应头, 因此也没有跨域的限制,没有什么过多的解释直接上代码吧。
前端部分

 

后端部分

 

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号(443 为 https 的默认值),以及主机 (两个页面的模数 设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

用途

1.页面和其打开的新窗口的数据传递
2.多窗口之间消息传递
3.页面与嵌套的 iframe 消息传递

用法

  • otherWindow: 其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
  • message: 将要发送到其他 window 的数据。
  • targetOrigin: 通过窗口的 origin 属性来指定哪些窗口能接收到消息事件.
  • transfer(可选) : 是一串和 message 同时传递的 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权

示例

index.html

 

another.html

 

从第 7 种到第 9 种方式,我觉得别人的写的已经很好了,为了完整性,我就拿别人的了。如有雷同....(不对,就是雷同....)不要说不出来。
该方式只能用于二级域名相同的情况下,比如适用于该方式。 只需要给页面添加 表示二级域名都相同就可以实现跨域。

 
 
 

实现原理

原理就是通过 url 带 hash ,通过一个非跨域的中间页面来传递数据。

实现流程

一开始 a.html 给 c.html 传一个 hash 值,然后 c.html 收到 hash 值后,再把 hash 值传递给 b.html,最后 b.html 将结果放到 a.html 的 hash 值中。 同样的,a.html 和 b.htm l 是同域的,都是 ,而 c.html 是

 
 
 

 

b.html 为中间代理页,与 a.html 同域,内容为空。

 
 

通过 iframe 的 src 属性由外域转向本地域,跨域数据即由 iframe 的 window.name 从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

非特殊必要情况,不建议使用。

Windows

 

Mac

这个目录可以自定义.

 

CORS 为什么要区分『简单请求』和『预检请求』?

到此这篇跨域是什么错误码(跨域请求是什么)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 二级域名解析ip查询(二级域名解析ip查询命令)2025-04-22 08:09:06
  • 文件权限755用符号表示(文件权限755用符号表示是什么)2025-04-22 08:09:06
  • ddp贸易术语解释(ddp贸易术语解释图解)2025-04-22 08:09:06
  • k8s版本区别(k8s稳定版本)2025-04-22 08:09:06
  • 上一章返回目录下一章(上一章返回目录下一章怎么操作)2025-04-22 08:09:06
  • qq账号要实名认证吗(qq账号要实名认证吗怎么弄)2025-04-22 08:09:06
  • 合并数组中有相同属性的对象怎么办(合并数组中有相同属性的对象怎么办啊)2025-04-22 08:09:06
  • auto的中文翻译(auto中文怎么说)2025-04-22 08:09:06
  • ubuntu源代码安装(ubuntu配置安装源)2025-04-22 08:09:06
  • 颜色代码查询工具(颜色代码查询工具下载)2025-04-22 08:09:06
  • 全屏图片