1. jsonp请求

jsonp的原理是利用 script 标签的跨域特性,可以不受限制地从其他域中加载资源,类似的标签还有 img。

缺点:只支持GET请求而不支持POST等其他类型的HTTP请求。

<script>
//回调函数,用来发送给 php服务器
function getData(data) {
console.log(data);
} //核心本质 就是后端服务器 返回一个函数调用 getData('js')
createJsonp(); function createJsonp() {
const s = document.createElement('script');
s.src='http://localhost/data.php?callback=getData';
document.body.appendChild(s);
}
</script>
<?php
//跨域必须允许,后台说了管用
//header('Access-Control-Allow-Origin:*');
$receive=$_GET["callback"]; // 拿到回调函数,可以用来判断
$arr = [
[
'id'=>1,
'name'=>'追梦',
'age'=>18
],
[
'id'=>2,
'name'=>'阿飞',
'age'=>18
]
]; //编译成字符串
echo json_encode($arr);
?>

2. document.domain

这种方法用在主域名相同子域名不同的跨域访问中。举个例子:http://a.frame.comhttp://b.frame.com 他们的主域名都是frame.com 这两个域名中的文件可以用这种方式进行访问,通过在两个域中具体的文件中设置document.domain="frame.com"就可达到跨域访问的目的。

实际应用中常常用在iframe中窗口之间的访问,根据浏览器的同源策略,浏览器中不同域的框架之间是不能进行js的交互操作的,所以一个窗口是不能拿到另一个窗口中的contentWindow对象的属性和方法的(注意是能拿到contentWindow对象的,只是属性和方法都不可用)。

为了能拿到数据,只要在两个iframe中分别写入document.domain="主域名",这样设置之后,就能拿到contentWindow对象的属性和方法了。

3. window.name

window的name属性有个特征:在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口在载入过的所有页面中的,并不会因新页面的载入而进行重置。

比如我在a.html这个页面中设置了window.name="a";然后让window重新加载b.html页面,然后在b.html页面中输出window.name会发现window.name=“a”。所以就算a.html和b.html这两个页面不是在同一个域中的,也可以在b页面中拿到a页面设置的window.name的值,跨域的核心思路就是这个原理。

例子:getDomainData.html是获取数据的页面,null.html是一个和getDomainData.html同域的空页面,它的作用是作为一个中转站,进行数据的过渡。data.html是要获取数据的所在页面,这里有着我们要的数据,它和getDomainData.html处于不同域中,所以取数据是跨域访问。

具体的过程是这样的:在getDomainData.html中建立一个子页面iframe,把这个iframe的src指向b.com/data.html,这样当这个iframe加载完成后就可以访问到data.html中的window.name的数据,之后再将iframe的src改为a.com/null.html,跳回getDomainData.html的同一个域,这样根据同源策略,getDomainData.html就可以访问到null.html中取得的data.html的数据了。获取数据以后最好销毁这个iframe,释放掉内存,也保证了安全。

getDomainData.html:

<script type="text/javascript">
var flag=0;
var data;
var iframe=document.createElement("iframe");//创建一个中转站iframe
document.appendChild(iframe); getData=function(){ //iframe加载完成后调用的处理函数
if(flag==1){
data=iframe.contentWindow.name; //读取b.html中的window.name
}else{
flag=1;
iframe.src="http://a.com/null.html";//跳回getDomainData.html的同一个域
}
}; iframe.src="http://b.com/data.html";//设置src到要获得数据的域中的对应页面 if (iframe.attachEvent) { //兼容IE,监听iframe加载完成
iframe.attachEvent('onload', getData);
} else {
iframe.addEventListener('load',getData);
}
</script>

data.html:

<script>
window.name="被获取数据"//简单的一行代码
</script>

最后的iframe销毁:

<script>
iframe.contentWindow.document.write(""); //情况iframe中的内容
iframe.contentWindow.close(); //避免iframe的内存泄漏
document.body.removeChild(iframe); //移除iframe节点
</script>

4. window.postMessage

window.postMessage是html5中实现跨域访问的一种新方式,可以使用它来向其它的window对象发送消息,无论这个window对象是否属于同源或不同源。

5. CORS

使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是应该失败。

6. Web Sockets

在js创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web socket协议。

详情参见大佬总结:https://segmentfault.com/a/1190000008525104

JavaScript跨域方式总结的更多相关文章

  1. JavaScript 跨域:window.postMessage 实现跨域通信

    JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...

  2. Javascript几种跨域方式总结

    在客户端编程语言中如javascript,同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法.只有当两个域具有相同的协议,相同的主机,相同的端口时,我们就认定 ...

  3. JavaScript跨域解决方式

    平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种: 1.jsonp解决跨域问题 客户端代码: <!DOCTYPE html> <ht ...

  4. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  5. 「JavaScript」JS四种跨域方式详解

    原文地址https://segmentfault.com/a/1190000003642057 超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript ...

  6. JavaScript 跨域漫游

    前言: 最近在公司做了几个项目都涉及到了iframe,也就是在这些iframe多次嵌套的项目中,我发现之前对iframe的认识还是比较不足的,所以就静下心来,好好整理总结了iframe的相关知识:&l ...

  7. 利用javascript跨域访问cookie之广告推广

    在上一篇<说一说javascript跨域和jsonp>中,利用JSONP进行了跨域的数据访问,利用JS本身的跨域能力在远端生成HTML结构的方式完成了一个小广告. 在实际应用中, 跨域使用 ...

  8. 优雅绝妙的Javascript跨域问题解决方案

    关于Javascript跨域问题的解决方案已在之前的一片文章中详细说明,详见:http://blog.csdn.net/sfdev/archive/2009/02/13/3887006.aspx: 除 ...

  9. JavaScript跨域实现

    最近在做个上传文件的服务,其中包含一个上传的web页面.目的是想客户端页面嵌套这个web页面,然后直接将文件上传到服务器. 因为文件不同所以需要保存到的文件夹名称也不一样,所以客户端需要传递一个文件夹 ...

随机推荐

  1. c# 使用网站的身份验证及 Cookie 的获取与使用

    C# 的 Http 访问可以使用 .net 自带的  HttpWebRequest, WebClient, HttpClient 类.也可以使用开源库 RestSharp . RestSharp 的优 ...

  2. bootstrap-thymeleaf-分页

    1.HTML代码 <div th:fragment="paginater"> <ul th:id="paginaterUlID" th:if= ...

  3. 浏览器HTML自带懒加载技术

    对于目前的图片懒加载,我们一般采用的是通过第三方库或懒加载库来实现,但是该方式的显著问题就是,必须按顺序执行: 1.加载初始的 HTML 响应内容 2.加载懒加载库 3.加载图片 假如浏览器能直接支持 ...

  4. 2018-5-26-Latex-去掉行号

    title author date CreateTime categories Latex 去掉行号 lindexi 2018-05-26 10:32:25 +0800 2018-2-13 17:23 ...

  5. Yum与RPM

    Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的服务器自动下载 ...

  6. idea maven打jar包

    双击clean install 会在根目录targer生成文件(注意删除test和替换yml文件)

  7. RGBA的值0-255范围如何转换成0-1范围

    这样一个rgba(1,0,0,1) 如果我们要把它转换成 0-255范围 就是rgb分别乘以255 就是 rgba(255,0,0,1) 0-255转0-1范围 如 rgba(34,56,56,1)转 ...

  8. 数据结构---Java---String、StringBuilder、StringBuffer

    1.概述 1.1 String:不可变字符串 public final class String implements java.io.Serializable, Comparable<Stri ...

  9. 【leetcode】926.Flip String to Monotone Increasing

    题目如下: A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possib ...

  10. Docker 镜像添加模块

    Docker 镜像添加模块   1. 使用root用户进入一个新容器,不要用 --rm .否则退出容器的时候,容器没有了 docker run --user 0 -it --name superman ...