js跨域

作者: _士心_ | 来源:发表于2017-03-13 09:44 被阅读114次

jsonp

原理:
JSONP 利用 <script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。

<script type="text/javascript">   
    var localHandler = function(data){
    alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);    };    
</script>   
<script type="text/javascript" src="http://remoteserver.com/remote.js"></script>

远程的remote.js

localHandler({"result":"我是远程js带来的数据"});

我本地请求

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

请求flightResult.aspx获取的数据

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

调用的url中传递了一个code参数,告诉服务器我要查的是CA1998次航班的信息,而callback参数则告诉服务器,我的本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。

劣势: 支持get 安全性不高 (可以通过动态生成jsonp解决)

与ajax的区别
但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。

cors

document.domain+iframe(适用于主域名相同的情况)

在域名为http://server.example.com中的a.html

document.domain = 'example.com';
var $iframe = document.createElement('iframe');
$iframe.src = 'server.child.example.com/b.html';
$iframe.style.display = 'none';
document.body.appendChild($iframe);
$iframe.onload = function(){
    var doc = $iframe.contentDocument || $iframe.contentWindow.document;
    //在这里操作doc,也就是操作b.html
    $iframe.onload = null;
};

在域名为http://server.child.example.com中的b.html

document.domain = 'example.com'

这种形式方便归方便,但也有其方便带来的隐患

  • 安全性,当一个站点被攻击后,另一个站点会引起安全漏洞。

  • 若页面中引入多个iframe,要想操作所有iframe,domain需要全部设置成一样的。

HTML5中的postMessage

postMessage隶属于html5,但是它支持IE8+和其他浏览器,可以实现同域传递,也能实现跨域传递。它包括发送消息postMessage和接收消息message功能。

postMessage调用语法如下

otherWindow.postMessage(message, targetOrigin, [transfer]);

  • otherWindow : 其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
  • message : 将要发送到其他 window的数据,类型为string或者object。
  • targetOrigin : 通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。
  • transfer (可选) : 一串和message 同时传递的 Transferable 对象。

接收消息message 的属性有:

  • data :从其他 window 中传递过来的数据。
  • origin :调用 postMessage 时消息发送方窗口的 origin 。
  • source :对发送消息的窗口对象的引用。

示例如下:域名http://127.0.0.1:9000页面A通过iframe嵌入了http://127.0.0.1页面B,接下来页面A将通过postMessage对页面B进行数据传递,页面B将通过message属性接收页面A的数据

页面A发送消息代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>页面A</title>
</head>
<body>
    <h1>hello jsonp</h1>
    <iframe src="http://127.0.0.1/b.html" id="iframe"></iframe>
</body>
</html>
<script>
window.onload = function() {  
    var $iframe = document.getElementById('iframe');  
    var targetOrigin = "http://127.0.0.1";  
    $iframe.contentWindow.postMessage('postMessage发送消息', targetOrigin);  
}; 
</script>

页面B接收消息代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>页面B</title>
</head>
<body>
    <h1>hello jsonp</h1>
</body>
</html>
<script>
var onmessage = function (event) {
  var data = event.data;    //消息
  var origin = event.origin; //消息来源地址
  var source = event.source; //源Window对象
  if(origin === "http://127.0.0.1:9000"){
    console.log(data, origin, source);
  }
};
// 事件兼容简单处理
if (window.addEventListener) {
  window.addEventListener('message', onmessage, false);
}
else if (window.attachEvent) {
  window.attachEvent('onmessage', onmessage);
}
else {
  window.onmessage = onmessage;
}
</script>

运行结果如下

相关文章

  • 跨域

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

  • 跨域问题详解分析

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

  • 2021-02-23

    一、什么是跨域 二、vue.config.js 跨域配置

  • HTML-获取iframe元素的正确方法

    跨域相关文章详解js跨域问题JavaScript跨域总结与解决办法 解释最清楚的jsonpWhat is JSON...

  • JSONP、CORS、跨域

    跨域 同源:两个文档同源需满足:协议、域名、端口相同跨域:不同域之间相互请求资源,就算作“跨域“。js进行DOM操...

  • 怎么能学好Web前端开发,如何去解决JS跨域问题

    如何去解决JS跨域问题?怎么能学好Web前端开发?JavaScript跨域是指通过JS在不同的域之间进行数据传输或...

  • 如何去解决JS跨域问题 怎么能学好Web前端开发

    如何去解决JS跨域问题?怎么能学好Web前端开发?JavaScript跨域是指通过JS在不同的域之间进行数据传输或...

  • 关于js中的跨域

    @(JS技巧)[跨域] 各种跨域方法详解 总是在听说跨域,可是自己除了JSON,其它的方法其实并不是真的理解。今晚...

  • vue 跨域的配置

    关于跨域的配置真是累呀 在网上找了资料 才成功实现跨域了 其实主要在vue.config.js 来配置跨域

  • 3.跨域

    什么是跨域? js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过...

网友评论

    本文标题:js跨域

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