分类总结跨域解决方案应用

栏目: jQuery · 发布时间: 5年前

内容简介:笔者之前用过Nginx、Node.js、JSONP方法解决过前端跨域,最近项目上要公开一个方法给其他域下的页面调用,因此又接触到跨域,借此机会在这里分广义上的跨域是指一个域下的文档或者脚本试图请求另一个域下的资源。(ps:只要协议、主机、端口三者中任何一个不同,都被当作不同的域哦。)常见的跨域行为:

前言

笔者之前用过Nginx、Node.js、JSONP方法解决过前端跨域,最近项目上要公开一个方法给其他域下的页面调用,因此又接触到跨域,借此机会在这里分 AJAX方面 的跨域和 操纵JS交互脚本方面 的跨域这两个维度来进行简单总结。本文章是笔者第一篇掘金文章,算是对自己的监督,各位多多指教。

正文

1. 什么是跨域?

广义上的跨域是指一个域下的文档或者脚本试图请求另一个域下的资源。(ps:只要协议、主机、端口三者中任何一个不同,都被当作不同的域哦。)

常见的跨域行为:

a)、资源跳转:<a>标签跳转链接、重定向、表单提交;

b)、资源请求,<link>、<script>、<img>、<frame>的url请求,@font-face()的引用

c)、JS发起的脚本请求、DOM和JS对象的跨域操作

2. 同源策略

只有当协议、主机、端口三者都相同,才算同源。

        主要基于 安全考虑 ,浏览器设置了同源策略,如果“非同源”,浏览器会限制:

a)、网络方面:AJAX不能发送;

b)、DOM和JS对象无法获取、操作;

c)、Cookies、localStorage、IndexDB无法读取;

笔者将b、c点统称为操纵JS脚本方面的跨域,a点位AJAX的跨域。

3.AJAX方面的跨域解决方案

(1)document.domain + ifame

        原理:两个页面强制通过JS设置document.domain为基础主域,使得二者同域,实现跨域。

缺点:因document.domain设置有限制,因此只适用于 主域相同,子域不同 的场景。

实现:

  • 父窗口(http://mainDomain.com/a.html):

<iframe src="http://child.mainDomain.com/b.html"></iframe>

<script>

document.domain = 'mainDomain.com';      // 设置主域         

    var publicKey = 'value';       

</script>

  • 子窗口(http://child.mainDomain.com/b.html):

<iframe src="http://child.mainDomain.com/b.html"></iframe>

<script>

    document.domain = 'mainDomain.com'; // 设置主域

    console.log(parent.publicKey); // 成功访问父窗口的publicKey值

</script>

(2)document.hash+ ifame

        原理:父窗口可以对iframe的src进行读写,子窗口嵌套父窗口同域的页面,通过 parent.parent .callback访问父窗口JS,而服务器会忽视url中#后面的字符,通过浏览器的 hashchange 事件监控到 location.hash 的变化。这样就可以实现iframe之间的通讯。

例子: 实现不同域下的 a.html 和 b.html 之间的通信。

分类总结跨域解决方案应用

关键代码:

  • a.html
// 控制b.html的src并传值
document.getElementById('iframe').src = 'http:domain2.com/b.html#msg=hello';
// 对外暴露回调函数window.oncallback = function(){  
    // ... 回调函数
}复制代码
  • b.html
window.onhashchange = function(e) {       
    // location.hash,处理数据,通过proxy.html执行回调      
    document.getElementById('proxy').src = 'http:domain1.com/proxy#data=123';
}复制代码
  • proxy.html
window.onhashchange = function(e) {
    parent.parent.oncallback(loaction.hash)
}复制代码

(3)通过parent.parent.oncallback,通过嵌套iframe的代理窗口进行跨域

        原理和第2点类似,这一种比较简易优雅,通过窗口url的参数来通信。实现如下图:

分类总结跨域解决方案应用

(4)postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 2中的API,可以安全地实现跨域

方法:otherWindow.postMessage(message, targetOrigin, [transfer])

    otherWindow: 目标窗口;

         message: 向发送给其他window的数据(基本类型和对象,部分浏览器不支持对象);

targetOrigin:协议+主机+端口号,也可以设置为"*",目标源的限制

(5)window.name

        原理:同一个窗口的window.name属性会一直保存,刷新页面后仍保存,可以借此共享数据。

4. AJAX方面的跨域解决方案

(1)JSONP

        原理:浏览器同源策略没有限制<script>的跨域请求,基于这个原理,我们可以通过动态创建script,请求不同域的服务器,服务器返回回调函数来实现跨域通讯。

原生实现:

分类总结跨域解决方案应用

(2)反向代理,例如Nginx、Node.js等后端服务器代理

        原理:浏览器有同源策略限制AJAX请求,但服务器与服务器之间通讯没有限制,所以可以通过同源的代理服务器接受AJAX请求,从而实现跨域

(3)通过CORS跨域

    实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

总结

本文章把跨域分两大类来进行总结,总结要点式概括,有些方法只是一笔带过,又需要的同学可以查看掘金的其他详细类文章。

参考文章:


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms + Data Structures = Programs

Algorithms + Data Structures = Programs

Niklaus Wirth / Prentice Hall / 1975-11-11 / GBP 84.95

It might seem completely dated with all its examples written in the now outmoded Pascal programming language (well, unless you are one of those Delphi zealot trying to resist to the Java/.NET dominanc......一起来看看 《Algorithms + Data Structures = Programs》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码