JS跨域:jsonp、跨域资源共享、iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html

JS中的跨域

请求跨域有好多种,

一、跨域资源共享:

也就是设置服务端的header,可以指定哪些域名可以请求,也是最简单的跨域方式(自我感觉),并且可以支持post等等。

//指定允许其他域名访问
'Access-Control-Allow-Origin:*'//或指定域
//响应类型
'Access-Control-Allow-Methods:GET,POST'
//响应头设置
'Access-Control-Allow-Headers:x-requested-with,content-type'

二、jsonp

由于浏览器的同源策略,所以ajax不能直接跨域请求数据,我们把浏览器的安全策略组关掉(也就是关掉同源策略)就可以啦,当然这是开个玩笑。想了解可以访问这个网站:https://www.cnblogs.com/zhongxia/p/5416024.html

上面说的是ajax会被同源策略拦截下来,但是script中的src并不会被拦截,我们可以利用这个特性实现跨域:

<script>
//下面就输出你在服务端请求的数据
function dosomething(data){
console.log(data);
}
</script>
//src 就是你想要请求的地址,cb是请求时带的参数,这是必须要加的,因为上面的函数名也是这个
<script src="http://localhost:8080/ChickensSys/backDate?cb=dosomething"></script>

服务端要做相应的配合,这边是用javaweb来调试:在doGet函数里面添加这些代码:

        response.setContentType("text/html");
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String cbString = request.getParameter("cb");
PrintWriter out = response.getWriter();
out.println(cbString + "("this is jsonP ")");
out.flush();
out.close();

仔细看:out.println(cbString + "("this is jsonP ")");

我们把参数结果带入进去,可以发现输出的是cb("this is jsonP");相当于是调用这个函数,没错,结果就是这样。

你会看到页面的控制台打印了this isjsonP。

结论:我们用src(不会被同源策略拦截)请求别的域名的数据,返回的结果放在已定义好的函数参数里面并且执行这个函数,然后你要对数据做哪些操作就可以在函数里面随便操作。

三、window.name + iframe跨域获取数据

这个的原理和jsonP差不多吧,也是利用src,不过这次是利用iframe(可以理解html中一个内嵌页面,也可以包含一个html文件)的src和window.name的特性来跨域, window.name属性的神奇之处在于name 值在不同的页面(甚至不同域名)加载后依旧存在(如果没修改则值不会变化),并且可以支持非常长的 name 值(2MB)。也就是你第一次设置后,不管你的iframe重定向到哪个页面,window.name都不会变。

     <script type="text/javascript">
let iframe = document.createElement('iframe');
//src你请求的地址,此时会报错,说你跨域了
iframe.src = 'http://localhost:8080/ChickensSys/backDate';
document.body.appendChild(iframe);
iframe.onload = function() {
//在本地新建空白的proxy.html因为上面报错了,这边赶紧重定向到本地的proxy.html
iframe.src = 'proxy.html';
//contentWindow属性是指指定的frame或者iframe所在的window对象。
console.log(iframe.contentWindow.name)
};
</script>

服务端需要相应的配合:

out.println("<script>window.name = \"this is CORS</script>");

预期结果跟我们想的一样,一开始报错,我们重定向到本地后就没报错,输出结果也是没错的,因为服务端输出的是一个脚本,window.name=" ";还记得上面讲过window.name 值在不同的页面(甚至不同域名)加载后依旧存在(如果没修改则值不会变化)。但是为什么会一直调用onload函数呢,因为在onload函数中又被重定向所以又一次调用,跟递归差不多意思。既然可以拿到数据,那我们下面来改进下,让它不报错,并只拿到一次数据。

    <script>
let iframe = document.createElement('iframe');
iframe.style.display = 'none';
var state = 0;
iframe.onload = function() {
//重定向完,可以取window.name的数据了,这边可以对数据进行处理
if(state === 1) {
var data = iframe.contentWindow.name;
console.log(data);
//移除这个节点,其实上面display:none已经对dom无影响了,这个加了保险
document.body.removeChild(iframe);
//当下面的iframe.src执行到时,也就是第一次onload,迅速重定向到本地
} else if(state === 0) {
state = 1;
iframe.src = 'proxy.html';
}
};
iframe.src = 'http://localhost:8080/ChickensSys/backDate';
document.body.appendChild(iframe);
</script>

运行结果:

只有一次请求。

上面只是讲下原理,我们可以对上面做个封装,封装成一个函数,方便以后用:

    <script>
//url是请求的地址,handle是处理数据的函数
function getDataWithIframe(url, handle){
let iframe = document.createElement('iframe');
iframe.style.display = 'none';
var state = 0;
iframe.onload = function() {
//重定向完,可以取window.name的数据了,这边可以对数据进行处理
if(state === 1) {
handle(iframe.contentWindow.name);
//移除这个节点,其实上面display:none已经对dom无影响了,这个加了保险
document.body.removeChild(iframe);
//当下面的iframe.src执行到时,也就是第一次onload,迅速重定向到本地
} else if(state === 0) {
state = 1;
iframe.src = 'proxy.html';
}
};
iframe.src = url;
document.body.appendChild(iframe);
}
let url = 'http://localhost:8080/ChickensSys/backDate';
getDataWithIframe(url, function(data){
console.log('这是请求来的数据:' + data);
})
</script>

总结:看了好多跨域,大部分都是通过src来跨域的,但好像通过src的都只能是get请求,比如刚说的jsonP和iframe+window.name的方式都是通过get来请求数据,而且都是需要要后端进行相应的配合,比如jsonP需要加个cb()来执行函数,iframe需要<script>window.name=" "</script>来执行赋值语句,第一种设置后端的header的方式倒是可以支持post请求,真是又简单又好用。。。

JS跨域:jsonp、跨域资源共享、iframe+window.name的更多相关文章

  1. 跨域-jsonp、cors、iframe、document.domain、postMessage()

    同源策略 概念:同源: 协议.域名.端口号 完全相同 同源策略是浏览器的一种安全策略:且浏览器不会将违反同源策略的响应信息返回 http://127.0.0.1:3000/index.html     ...

  2. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  3. 跨域问题解决方案(HttpClient安全跨域 & jsonp跨域)

    1 错误场景 今天要把项目部署到外网的时候,出现了这样的问题, 我把两个项目放到自己本机的tomcat下, 进行代码调试, 运行 都没有问题的, 一旦把我需要调用接口的项目B放到其他的服务器上, 就会 ...

  4. 同源策略引发对跨域jsonp跨域的理解

    一,同源策略其实网络的安全基石,既:http://www.baidu.com:80协议(http或者HTTPS或者ws或者wss).域名(www.baidu.com).端口(默认80,可以不写 htt ...

  5. jQuery ajax的jsonp跨域请求

    一直在听“跨域跨域”,但是什么是跨域呢?今天做了一些了解.(利用jQuery的jsonp) jQuery使用JSONP跨域 JSONP跨域是利用script脚本允许引用不同域下的js实现的,将回调方法 ...

  6. js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)

    一.浏览器同源策略 首先我们需要了解一下浏览器的同源策略,关于同源策略可以仔细看看知乎上的一个解释.传送门 总之:同协议,domain(或ip),同端口视为同一个域,一个域内的脚本仅仅具有本域内的权限 ...

  7. 前端跨域问题相关知识详解(原生js和jquery两种方法实现jsonp跨域)

    1.同源策略 同源策略(Same origin policy),它是由Netscape提出的一个著名的安全策略.同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正 ...

  8. JSONP跨域资源共享的安全问题

    目录 关于 JSONP 一.JSON 劫持 二.Callback 可定义导致的安全问题 三.其他文件格式( Content-Type )与 JSON 四.防御 摘自:http://blog.known ...

  9. Ajax进阶之原生js与跨域jsonp

    什么是Ajax? 两个数求和: 用Jquery和数据用json格式 viws函数: from django.shortcuts import render,HttpResponse # Create ...

随机推荐

  1. 【JAVA】input.next().charAt(0);的含义

    接收键盘输入的字符串,并且取出它的第一个字符. 分析: Scanner scan=new Scanner(System.in); String s=scan.next(); //返回一个String ...

  2. linux Sersync 上配置客户端

    1.安装 Rsync 并配置相关权限 在 SERSYNC 上配置 RSYNC 客户端相关权限认证: [root@SERSYNC /]# yum install rsync -y [root@SERSY ...

  3. Maven中添加Jetty服务器配置

    <project> <!--其它配置--> <build> <plugins> <plugin> <groupId>org.mo ...

  4. 基于firebird的数据转存

    功能:使用于相同的表从一个数据库转存到另一数据库: 方式:直连fdb并加载django,引用django的model完成: 原因:1.select * from *** 返回的数有很多None,直接i ...

  5. 记一次 gunicorn 启动 flask 出问题的经历

    出错现象: gunicorn+nginx+flask 部署项目, 部署过程没问题,项目也正常启动了,但是一旦访问接口,就会报错: Traceback (most recent call last): ...

  6. ubuntu idea 安装

    一.下载 1.进入官网 下载对应安装包 https://www.jetbrains.com/idea/download/#section=linux sudo wget https://downloa ...

  7. MTV和MVC的区别

    著名的MVC模式:方便解藕 所谓的MVC就是把web应用分为三层 1.模型层: model     负责业务对象和数据库的对象(ORM)的映射 2.视图层       views 负责与用户的交互(书 ...

  8. Django ormmodel模型字段参考文章

    Model 字段参考 (Model field reference)¶ 本文档包含所有 字段选项 (field options) 的内部细节和 Django 已经提供的 field types . 参 ...

  9. Python全栈开发,Day1

    一.Python介绍及版本 Python崇尚优美.清晰.简单,是一个优秀并广泛使用的语言. 目前Python主要应用领域: 云计算:云计算最火的语言 WEB开发:众多优秀的WEB框架,众多大型网站均为 ...

  10. JS中的继承(原型链、构造函数、组合式、class类)

    1.继承 应注意区分继承和实例化,实例化是生成一个对象,这个对象具有构造函数的属性和方法:继承指的应该是利用父类生成一个新的子类构造函数,通过这个子类构造函数实例化的对象,具有子类的属性和方法,同时也 ...