美文网首页
跨域原理

跨域原理

作者: 饥人谷1904_陈俊锋 | 来源:发表于2019-07-11 14:34 被阅读0次

跨域:浏览器对于javascript的同源策略的限制,例如a.com下面的js不能调用b.com中的js,对象或数据(因为a.com和b.com是不同域),所以跨域就出现了。

同源策略:浏览器施加的安全限制,请求的url地址,必须与浏览器上的url地址处于同域上,也就是协议,域名和端口都相同。

通过ajax去向a.com:8080发请求 此时当前页面与请求端同域:获取数据成功 如果当前页面与请求端不同源(跨域):无法读写对方的资源

需要注意的是:对于当前页面来说页面存放的JS文件的域不重要,重要的是加载该JS页面所在什么域

那么下面我们开始探讨跨域的一些方式以及原理

1.JSONP

首先我们需要知道的是 HTML 中 script 标签可以加载其他域下的js,比如我们经常引入一个其他域下线上cdn的jQuery。

因此 可以利用这个特性实现从其他域下获取数据。

<script src="http://api.data.com/getInfo.php"></script>

这里我们会有一个疑问:我们向其他域数据接口发送请求,获取数据后作为 js 来执行,但是这里的数据是 JSON 格式的数据,如果直接作为 js 运行的话我们应该如何去得到这个数据,进而进行我们想要的操作呢?

<script src="http://api.data.com/getInfo.php?callback=showData"></script>

这个请求到达后端后,后端会去解析callback这个参数获取到字符串showData,在发送数据时做如下的处理:

之前后端返回的数据是:{ "info": "something" },现在返回的数据是:showData({ "info": "something" }),前端script标签在加载数据后会把 「 showData({ "info": "something" }) 」当作js来执行,实际上就是调用了showData函数,此时参数是 { "info": "something" }。用户只需要提前在页面定义好showData这个全局函数,在函数内部处理参数即可。

<script>
function showData(ret){
  ...
}
</script>
<script src="http://api.data.com/getInfo.php?callback=showData"></script>

所以总结来说JSONP是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行 提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。换句话说,JSONP 需要对应接口的后端的配合才能实现。

下面我们来演示一下:

请求端代码
同源获取数据 no problem
跨域获取数据 一样也是 no problem
当前页面通过添加script标签,向数据接口页面发送请求获取数据并当作 提前在当前页面声明好的一个函数的参数 去执行并操作数据。

2. CORS

跨域资源共享(Cross-Origin Resource Sharing),是一种ajax跨域请求资源的方式,支持现代浏览器,IE10以上。

实现方式:当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该响应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。

CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。

页面直接使用ajax发送请求


请求端

后端服务器发送响应时加上一个响应头


server.js

其中,res.setHeader('Access-Control-Allow-Origin','http://localhost:8080') 指的是后端允许的域名是 localhost: 8080;而 res.setHeader('Access-Control-Allow-Origin', '*') 则是允许任何人获取数据。

下面我们来演示一下(任何人都可以获取数据的情况):

同域


向a.com: 8080发送请求 在本域内

下面的截图显示的是 允许域名是 http://localhost: 8080 的用户跨域获取数据

域名是http://localhost: 8080

跨域


不同源也没有获得允许
同上

3. 降域

场景:当前页面存在/嵌套不同域的iframe

只有在相同域名的条件下,才能去访问iframe里面的东西
不同域名的条件下,iframe里面的东西可以被加载但是不能获取和被操作

阻止跨域使用frame,无法实现跨域操作 同域允许操作iframe 利用document.domain降域之后彼此可以相互访问
document.domain = 'jrg.com' 在两者中把二者降到 'jrg.com' 主域下,使二者之间可以实现相互访问
前提是 域名要有相同的末尾段主域可降

4. postMessage

没有主域限制

嵌套跨域 iframe 的页面

// 当需要对iframe进行一定操作时
// 向当前iframe postMessage一个消息
// * 表示任何域下都可以接受
window.frames[0].postMessage(this.value,'*');

被嵌套的 iframe 本域的页面/接口

// 监听message事件(从中知道是否有人嵌套了本地iframe并向本地发送了消息)获取了消息数据并做对应的事情
// 可以定义出一些接口告知嵌套方要操作iframe可以发送消息
// 本地内部对消息有一些实现(通过嵌套方发送消息来修改一些东西)
window.addEventListener('message',function(e) {
    $('.main input').value = e.data
    console.log('b get:' + e.data);
});

首先,aa.html可以向bb.html postMessage消息


aa.html

bb.html监听到message消息做出对应的事情


bb.html
简单的postMessage演示

参考 饥人谷 / 跨域

相关文章

  • 响应头设置跨域和Spring注解跨域

    CORS跨域原理详解Spring解决跨域 响应头设置跨域 Spring注解跨域@CrossOrigin 可添加到方...

  • 跨域

    跨域 什么是跨域: 解决跨域 通过jsonp原理:在页面引入跨域js和css时,没有存在跨域问题.因此可以动态创建...

  • 跨域问题详解分析

    参考文档 CORS详解 跨域资源共享 CORS 详解 js中几种实用的跨域方法原理详解 跨域的那些事儿 跨域与跨域...

  • 跨域请求原理

    跨域请求原理

  • 前端跨域

    什么是ajax跨域 ajax跨域的原理 ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”,可以参...

  • 跨域与常用方案

    本文源自一次内部关于跨域的讨论分享的总结 理解跨域的重点在于:了解跨域产生的场景、原理 跨域问题只在浏览器客户端环...

  • ajax跨域请求

    ajax跨域请求(jsonp) 利用JSONP解决AJAX跨域问题的原理与jQuery解决方案JSONP jQue...

  • 跨域的解决方式

    一、 JSONP操作跨域 原理:利用 标签没有跨域限制(可以加载其它域选下的js),网页可以得到从其他来源动态...

  • 做demo和学习过程当中遇到的一些问题,收集的博文

    轻松搞定JSONP跨域请求--->关键字: 跨域, 同源策略, JSONP原理 git拉取远程分支到本地 git ...

  • 跨域原理

    跨域:浏览器对于javascript的同源策略的限制,例如a.com下面的js不能调用b.com中的js,对象或数...

网友评论

      本文标题:跨域原理

      本文链接:https://www.haomeiwen.com/subject/svcrkctx.html