美文网首页前端开发随笔-生活工作点滴
进阶篇:同源策略 & 跨域(17)

进阶篇:同源策略 & 跨域(17)

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

饥人谷学习进阶第 17 天

关于跨域拓展:

服务器端中转跨域
JSONP、CORS 这两种跨域请求方式都需要对方服务器支持。

假设页面为 https://jirengu.github.io/weather/weather.html, 需要向 https://weather.com/now 这个接口发送请求获取数据,但此接口不支持JSONP 和 CORS跨域。

可以这样做:

  1. 搭建服务器,创建接口,如 https://api.jirengu.com/weather
  2. 设置这个接口允许 CORS 跨域
  3. 我们的页面向自己的这个接口发请求
  4. 接口收到请求后,在服务器端向https://weather.com/now 这个接口要数据(在服务端不存在同源策略限制),拿到数据后,返回给前端页面

withCredentials

当前请求为跨域类型时是否在请求中协带cookie

假设 我们的页面为 https://jirengu.github.io/notebook/index.html, 需要向 https://note-server.jirengu.com.com/isLogin (此接口设置了 CORS 跨域支持)这个接口发发送请求获取用户是否登录的信息。

在发送请求的时候,需要设置 withCredentials = true, 那么请求的时候会带上 cookie 信息。否则请求不带上 cookie,后端接口会认为一直处于未登录状态。

用法:

var xhr = new XMLHttpRequest()
xhr.withCredentials = true
xhr.open('GET', 'https://note-server.jirengu.com.com/isLogin', true)
xhr.onload = function() {
  console.log('withCredentials: ', xhr.withCredentials)
}
xhr.send()

同源策略

浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。

本域是指:

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

跨域方法

JSONP

HTML 中 script 标签可以加载其他域下的js,比如我们经常引入一个其他域下线上cdn的jQuery。可以利用这个特性实现从其他域下获取数据。

示例:

<script src="http://api.jirengu.com/weather.php"></script>

这时候会向天气接口发送请求获取数据,获取数据后做为 js 来执行。 但这里有个问题, 数据是 JSON 格式的数据,直接作为 JS 运行的话我如何去得到这个数据来操作呢

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

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

之前后端返回数据: {"city": "hangzhou", "weather": "晴天"} 现在后端返回数据: showData({"city": "hangzhou", "weather": "晴天"}) 前端script标签在加载数据后会把 「showData({“city”: “hangzhou”, “weather”: “晴天”})」做为 js 来执行,这实际上就是调用showData这个函数,同时参数是 {“city”: “hangzhou”, “weather”: “晴天”}。 用户只需要在加载提前在页面定义好showData这个全局函数,在函数内部处理参数即可。

<script>
function showData(ret){
console.log(ret);
}
</script>
<script src="http://api.jirengu.com/weather.php?callback=showData"></script>

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


CORS

跨域资源共享(Cross-Origin Resource Sharing),是一种ajax跨域请求资源的方式,支持现代浏览器,IE10以上。实现方式:当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该响应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。

页面直接使用ajax发送请求
后端服务器发送响应时加上一个响应头:

res.setHeader('Access-Control-Allow-Origin','http://localhost:8080') // 后端允许的域名是localhost:8080
//res.setHeader('Access-Control-Allow-Origin','*') 允许任何人获取数据
res.end(JSON.stringify(news))

降域

场景:不同域下iframe的操作

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


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(e.data);
});

相关文章

  • 进阶篇:同源策略 & 跨域(17)

    饥人谷学习进阶第 17 天 关于跨域拓展: 服务器端中转跨域JSONP、CORS 这两种跨域请求方式都需要对方服务...

  • H5跨域访问

    跨域访问是源于浏览器的同源策略而引申出来的概念 1、先了解什么是同源策略和跨域访问 同源策略、跨域解决方案 - R...

  • H5 知识点 - 收藏集 - 掘金

    跨域解决方案总结 - 前端 - 掘金为什么需要跨域? 就得先知道同源策略. 同源策略 同源策略是为了保证数据的安全...

  • 通过script标签实现跨域

    跨域 什么是跨域? 跨域问题是由于javascript语言安全限制中的同源策略造成的。同源策略是由Netscape...

  • 前端基础(问答23)

    keywords: 同源策略、跨域、jsonp。 什么是同源策略(same origin policy) 同源:协...

  • 有关跨域的相关问题和方法

    跨域是什么 同源策略 在讲解什么是跨域之前先要清楚什么是同源策略,“同源政策”(same-origin polic...

  • 同源策略,跨域请求处理

    跨域访问 - 跨域请求 同源策略 适用于浏览器的一种资源访问策略;同源策略(Same origin policy)...

  • 无星的Egg之旅(一)——跨域

    先说点老生常谈的问题 啥是跨域 1.同源策略 要了解跨域,先要说说同源策略。同源策略是由 Netscape 公司提...

  • 同源策略 & 跨域

    1. 同源策略(Same origin Policy) 浏览器处于安全方面的考虑,只允许与本域下的接口交互。不同源...

  • 同源策略和跨域

    什么是跨域问题? 为什么会出现跨域问题? 因为浏览器的同源策略(同源指的是:协议+域名+端口相同)。 同源策略是浏...

网友评论

    本文标题:进阶篇:同源策略 & 跨域(17)

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