跨域(无代码版)

本文详细介绍了跨域及其原因,包括同源策略的定义和作用。重点讲解了实现跨域的多种方法,如JSONP、CORS、HTML5 postMessage、修改document.domain、WebSocket、Node中间件代理、Nginx反向代理和iframe技术,对比了各自的优缺点,总结了CORS作为根本解决方案的重要性和JSONP在兼容旧浏览器上的价值。
摘要由CSDN通过智能技术生成

在这里插入图片描述

同源

同源:域名、协议、端口均相同 (子域名和主域名也算其中)

协议子域名主域名端口号请求资源地址
http://wwwabc.com8080script/

同源策略是浏览器的一种安全措施

如果缺少了同源策略,浏览器很容易受到 XSS、CSFR 等攻击


同源策略限制了以下行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 和 JS 对象无法获取
  • Ajax请求发送不出去

跨域

跨域:浏览器由于同源策略(安全措施),不能执行其他网站的脚本。

不同域之间相互请求资源,就算作“跨域”。

但是,有三个标签允许跨域加载资源

<img src=XXX>
<link href=XXX>
<script src=XXX>

注意:域名和域名对应ip相同,也算跨域

  1. 如果是协议端口造成的跨域问题,“前台”是无能为力的。

  2. 在跨域问题上,仅仅是通过**“URL 的首部”(即同源三条件)**来识别,而不会根据域名对应的 IP 地址是否相同来判断。

  3. 产生跨域,请求能够发送出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。


实现跨域

1、JSONP(JSON with Padding)

利用了<script>不受同源策略的限制(😛上面说的三个标签允许跨域加载资源)

网页可以得到从其他来源动态产生的 JSON 数据

JSONP 请求一定需要对方的服务器做支持才可以


① JSONP 是什么

JSONP 是 JSON 的一种“使用模式”


② JSONP 和 AJAX 对比

JSONP 和 AJAX 相同,都是客户端服务器端发送请求,从服务器端获取数据的方式。

但 AJAX 属于同源策略,JSONP 属于非同源策略(跨域请求)


③ JSONP 的实现流程

优点:简单兼容性好

缺点:只能支持get方式,易受到 XSS 攻击


2、CORS(Cross-Origin Resource Sharing)跨域资源共享

CORS 属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。

浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。


当使用XMLHttpRequest发送请求时,如果浏览器发现违反了同源策略就会自动加上一个请求头origin

后端在接受到请求后,确定响应后会在Response Headers中加入一个属性Access-Control-Allow-Origin,即开启了CORS;

浏览器判断响应中的Access-Control-Allow-Origin值是否和当前的地址相同,匹配成功后才继续响应处理,否则报错


设置 CORS 会在发送请求时出现两种情况,分别为简单请求和复杂请求。


① 简单请求
  1. 使用请求方法为:
    • HEAD
    • GET
    • POST
  2. Content-Type 的值仅限于下列三者之一:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器;

XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。


② 复杂请求

复杂请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

简单来说,不符合简单请求的就是复杂请求

缺点:忽略 cookie,浏览器版本有一定要求


3、HTML5 postMessage 方法

postMessage 是 HTML5 XMLHttpRequest Level 2 中的 API,且是为数不多可以跨域操作的 window 属性之一,它可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的 iframe 消息传递
  • 上面三个场景的跨域数据传递

允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本、多窗口、跨域消息传递


缺点:浏览器版本要求,部分浏览器要配置放开跨域限制


4、修改 document.domain 跨子域

相同主域名下的不同子域名资源,设置 document.domain 为 相同的一级域名

缺点:同一一级域名;相同协议;相同端口


5、基于 HTML5 websocket 协议

Websocket 是 HTML5 一种新的协议,基于该协议可以做到浏览器与服务器全双工通信,是跨域的一种解决方案。

WebSocket 和 HTTP 都是应用层协议,都基于 TCP 协议。

但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 serverclient 都能主动向对方发送或接收数据。

同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 clientserver 之间的双向通信就与 HTTP 无关了。


原生 WebSocket API 使用起来不太方便,我们使用Socket.io,它很好地封装了 webSocket 接口,提供了更简单、灵活的接口,也对不支持 webSocket 的浏览器提供了向下兼容。


缺点:浏览器一定版本要求,服务器需要支持 websocket 协议


6、Node 中间件代理(两次跨域)

既然浏览器不让我们跨域传递数据,那我我们就绕开浏览器,从服务器走

即,服务器向服务器请求就无需遵循同源策略

我们使用一个中间商来转接请求,这个中间商就是代理服务器,那么就实现了从服务器到服务器

在这里插入图片描述


7、代理跨域请求(Nginx反向代理)

实现原理类似于 Node 中间件代理,需要你搭建一个中转 nginx 服务器,用于转发请求。

前端向发送请求,经过代理,请求需要的服务器资源


使用 nginx 反向代理实现跨域,是最简单的跨域方式。

只需要修改 nginx 的配置即可解决跨域问题,支持所有浏览器,支持 session,不需要修改任何代码,并且不会影响服务器性能。

实现思路:通过 nginx 配置一个代理服务器(域名与 domain1 相同,端口不同)做跳板机,反向代理访问 domain2 接口,并且可以顺便修改 cookie 中 domain 信息,方便当前域 cookie 写入,实现跨域登录。


缺点:需要额外的代理服务器


8、iframe

(1) window.name + iframe

name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

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


(2) location.hash + iframe

a.html 欲与 c.html 跨域相互通信,通过中间页 b.html 来实现。 三个页面,不同域之间利用 iframelocation.hash 传值,相同域之间直接 js 访问来通信。


(3) document.xxx + iframe

该方式只能用于二级域名相同的情况下,比如 a.test.comb.test.com 适用于该方式。

通过 iframe 是浏览器非同源标签,加载内容中转,传到当前页面的属性中


缺点:页面的属性值有大小限制


总结

  • CORS 支持所有类型的 HTTP 请求,是跨域 HTTP 请求的根本解决方案
  • JSONP 只支持 GET 请求,JSONP 的优势在于支持老式浏览器,以及可以向不支持 CORS 的网站请求数据。
  • 不管是 Node 中间件代理还是 nginx 反向代理,主要是通过同源策略对服务器不加限制。
  • 日常工作中,用得比较多的跨域方案是 corsnginx 反向代理

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值