浏览器的同源政策是什么?如何解决跨域问题?ajax如何实现跨域?

一、浏览器的同源政策是什么?

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。——来自MDN解析

简单来说就是:一个域下的 js 脚本在未经允许的情况下,不能够访问另一个域的内容

浏览器同源是指协议、端口、域名必须一样的,不然就不是同一个域的


二、浏览器同源政策有哪些限制?

目的:为了保护用户的信息安全,也是对 js 脚本的限制,不是对浏览器的限制,一般来说 img、script
请求都不会有跨域的限制,因为这些操作都不会通过响应结果来进行可能出现安全问题的操作

1.限制 JS 不能访问别的域里面的东西,cookie,localStorage,indexDB
2. 限制当前域下的 js 不能访问其他域的 DOM
3. 当前的ajax 不能发布跨域请求


三、如何解决跨域问题?

如果只需要实现主域名下的不同子域名的跨域操作,可使用 document.domain

  • 将 document.domain 设置为主域名,来实现相同子域名的跨域操作,这个时候主域名下的 cookie 就能够被子域名所访问。
  • 同时如果文档中含有主域名相同,子域名不同的 iframe 的话,我们也可以对这个 iframe 进行操作。

如果是想要解决不同跨域窗口间的通信问题,可以使用 location.hash 或者 window.name 或者 postMessage 来解决。

比如说一个页面想要和页面的中的不同源的 iframe 进行通信的问题,我们可以使用上面的方法解决

(1) location.hash ,我们可以在主页面动态的修改 iframe 窗口的 hash 值,然后在 iframe 窗口里实现监听函数来实现这样一个单向的通信。因为在 iframe 是没有办法访问到不同源的父级窗口的,所以我们不能直接修改父级窗口的 hash 值来实现通信,我们可以在 iframe 中再加入一个 iframe ,这个 iframe 的内容是和父级页面同源的,所以我们可以 window.parent.parent 来修改最顶级页面的 src,以此来实现双向通信。

(2) window.name ,主要是基于同一个窗口中设置了 window.name 后不同源的页面也可以访问,所以不同源的子页面可以首先在 window.name 中写入数据,然后跳转到一个和父级同源的页面。这个时候级页面就可以访问同源的子页面中 window.name 中的数据了,这种方式的好处是可以传输的数据量大。

(3) postMessageh5 中新增的一个 api。通过它我们可以实现多窗口间的信息传递,通过获取到指定窗口的引用,然后调用 postMessage 来发送信息,在窗口中我们通过对 message 信息的监听来接收信息,以此来实现不同源间的信息交换。

四、ajax 无法提交跨域请求怎么办?

我们可以使用 jsonp、cors、websocket 协议、服务器代理来解决问题。

(1)jsonp, 实现跨域请求是通过动态构建 script 标签来实现跨域请求,上面有提到说跨域请求是对 js 的限制,像 img 和 script 是不限制的,这个就是利用这一点,通过请求的 url 后制定一个回调函数,然后服务器在返回数据时候,构建一个 json 的数据包,这个包就是回调函数,然后返回给前端。又因为请求的是脚本文件,所以就会直接执行,这样子我们提前定义好的回调函数就可以被调用,从而实现了跨域请求的处理。

不过这个只用于 get 请求。 如果看过 JSONP 库的源码就知道,常见的实现代码其实就是 document.createElement('script') 生成一个 script 标签,然后插 body ,哪有设置请求格式的余地,不是 get 是啥

(2)CORS,一个 W3C 标准,全称是跨域资源共享。需要浏览器和服务器同时支持,现在大部分浏览器都支持,所以咱们考虑服务器就好了。

(3)webscokt,一句话,这个协议没有同源限制。

PS: 为什么 webscokt 协议没有同源限制?

因为 websocket 使用类似 ws:// 这样的方式进行连接,并不是使用 http 协议进行数据传输,所以浏览器的无法限制它。

而且人家本来就是设计成支持跨域访问的协议的(滑稽),在 websocket 请求的请求头中会像 CORS 一样加入 origin 字段,服务端可以根据这个字段来判断是否通过该请求,是不是很奈斯!

(4)使用服务器来代理跨域的访问请求,相当于是把工作场地换了,换成后端代请求,然后把获取的结果返回给前端。


额外说一嘴子:CORS 分简单请求和非简单请求:
  • 简单请求:会在头信息添加 Origin 字段,说明来自哪个源,服务器根据这个值里决定是否同意这个请求,发现 Origin 在允许的范围内,服务器就会返回一个正常的 HTTP 回应,会包含 Access-Control- 开头的字段。

    如果是不允许的范围内,这个回应头信息就不会携带 Access-Control-Allow-Origin 字段,就会抛出一个错误,ajax 就不会得到响应消息

  • 非简单请求:在发送请求之前会搞一个预检请求,来判断该域名是否在服务器的白名单中,收到肯定回复后才会发起请求,不然连发起请求的资格都没有哦(太惨了)

感谢你看到这里,笔芯❤,对你有帮助的话留个赞呗,咪揪~


参考文章:https://github.com/CavsZhouyou/
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值