js跨域

第一次写博客,好紧张,不知道能写成啥样,哈哈哈。

自己的一知片解,有错请多多指教,嘻嘻嘻。

一、何为跨域?

只要协议、域名、端口后任何一个不同,就是跨域。

举个例子:

http://www.example.com 协议不同
https://www.example.com
http://www.example.com 域名不同
http://www.test.com
http://www.example.com 端口不同
http://www.example.com:81

注意:ip相同,域名不同,也是跨域。(在本地写demo时,配置host文件,127.0.0.1配置了两个域名,纠结是否算跨域,试了一下,是的)

二、跨域的类型

1.cookie

只有同源的网页才能共享cookie

2.iframe

网格网页不同源,无法拿到对方的DOM

3.ajax

只能请求同源的网址,否则报错

三、解决跨域

我在我电脑的host文件里配置了两个域名模拟跨域。

以下,test1代表www.test1.myhost.com; test2代表www.test2.myhost.com

1.cookie

存在这样一种情况能够实现共享cookie:两个网页一级域名形同,二级域名不同,设置cookie时,指定两个网页的domain相同,便可以共享cookie啦。

test1:

document.cookie = ‘key1= value1; domain=myhost.com‘;console.log(document.cookie);//"key1 = value1"

test2:

console.log(document.cookie);//"key1 = value1"

就酱紫,他俩共享cookie了,好可怕

打开application看看,发现这cookie原来在myhost.com域名下。

2.iframe

一个页面中嵌套一个iframe,这个iframe的src与主页面跨域。这样的话,主页面获取操作iframe的DOM,iframe也无法操作主页面的DOM

test1为主页面,test2为嵌入的iframe

解决iframe跨域的,宝宝只知道这三种:

(1)片段识别符

(2)window.name

(3)window.postMessage

2.1 片段识别符

指的是URL中#后面的部分,只改变片段识别符,页面不会重新刷新。

实现思路:

父窗口可以把要传递的数据写入iframe的src片段识别符中,iframe通过监听hashchange事件得到通知,获取数据

同样道理,子窗口也可以改变父窗口的片段识别符,达到同样的效果。示例来喽:

父→子:

主页面

var origin  = $(‘iframe‘).attr(‘src‘);
$(‘iframe‘).attr(‘src‘, origin + ‘#主窗口‘);

iframe

console.log(window.location.hash);//"#主窗口"

子→父:

iframe

parent.location.href =‘http://www.test1.myhost.com:8080/tutor/cookie#iframe‘

主页面

console.log(window.location.hash);//"#iframe"

2.2 window.name

浏览器窗口有window.name属性,它的特点是无论是否同源,只要在同一个窗口中,前一个网页设置了这个属性,后一个网页就可以读取它

实现思路:

将iframe需要与主页面传递的数据写到iframe的window.name中,完成后将iframe的src设置成与主页面同源,此时,主页面与iframe就同源了,就可以拿到对方的数据啦,而iframe的src更改并不影响window.name的值啊,主页面便可以轻松读取iframe中window.name的值啦,是不是很机智!再来个例子吧。

iframe

window.name = ‘哈哈哈,我是iframe‘;
location.href = ‘http://www.test1.myhost.com:8080/这里就是一个与主页面同源的页面‘;

主页面

console.log($(‘iframe‘)[0].contentWindow.name);//"哈哈哈,我是iframe"

2.3 window.postMessage

html5引入的新API,允许跨窗口通信,不论这两个窗口是否同源。

window.postMessage(data, url); //data为要传给目标的数据,url为目标的url。

注意,此window是目标窗口的window,不是本窗口的window

同样来个例子:

子→父:

iframe

top.postMessage(‘hello‘, ‘http://www.test1.myhost.com:8080/tutor/cookie‘);

主页面

window.addEventListener(‘message‘, function(e) {
  console.log(e.data);//"hello"
}, false);

父→子:

主页面

$(‘.post‘).on(‘click‘, function() {
   $(‘iframe‘)[0].contentWindow.postMessage(‘hello hello‘, ‘http://www.test2.myhost.com:8080/这里就是一个目标url‘);
});

iframe

window.addEventListener(‘message‘, function(e) {
  console.log(e.data);//"hello hello"
}, false);

这里的e有几个重要属性:

a.data:传递来的message

b.source:发送消息的窗口对象

c.origin:发送消息窗口的源(协议+主机+端口号)

3.ajax

诶嘿,宝宝知道的也是三种,哈哈哈,好巧啊

(1)JSONP

(2)websocket

(3)CORS

分别说说吧

3.1 JSONP

原理就是利用script脚本拥有跨域能力。

基本思想是,网页添加一个script元素,src放需要请求的接口,这种做法不受同源策略的限制。服务器收到请求后,将数据放在一个指定的回调函数里传回来。

这种方法简单适用,老式的浏览器全部支持,服务器改造也非常小。

js实现:

function addScriptTag(src) {
  var script = document.createElement(‘script‘);
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

$(‘.ajax‘).on(‘click‘, function() {
  addScriptTag(‘http://www.php.myhost.com/jsonp.php?callback=foo‘);
});

function foo(data) {
  console.log(‘response data is: ‘ + data);
};

jQuery实现:

$(‘.ajax‘).on(‘click‘, function() {
  $.ajax({
    url: ‘http://www.php.myhost.com/jsonp.php‘,
    type: ‘get‘,
    dataType: ‘jsonp‘,
    jsonpCallback: ‘foo‘,
    data: {}
  });
});

function foo(data) {
  console.log(‘Your response is: ‘ + data);
};

PHP代码:

<?php

$callback = $_GET[‘callback‘];
$data = ‘hello‘;
echo $callback.‘(‘.json_encode($data).‘)‘;

?>

3.2 websocket

websocket是一种通信协议。该协议不实行同源策略,只要服务器支持,就可以通过它进行跨源通信。

例如,长连接呀

其实不太懂,就先不说它了哈

3.3 CORS

开始扯啦

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。

CORS请求分为两类:简单请求和非简单请求,太多了,这里就先不介绍了,一查就知道了。

简单请求就是浏览器发出CORS请求时,http头当中增加一个域(origin)的信息。该域包含协议名、地址及一个可选的端口,用来说明本次请求来自哪个源,服务器根据这个值决定是否同意这次请求。(这都是浏览器代为发送,开发者的代码无法触及到)

如果这个指定的源不在许可范围内,服务器就返回一个正常的http回应。但是回应中没有Access-Control-Allow-Origin字段,抛出异常,XMLHttpRequest的onerror捕获。

如果这个指定的源在许可范围内,会多出几个头信息字段(都以Access-Contrl-开头)

非简单请求(我平常请求的接口都是非简单请求,因为content-type为application/json)是在发起正式通信之前增加一次http查询,实现询问服务器当前网页所在域名是否在许可名单中,得到肯定答复后浏览器才会发出正式的XMLHttpRequest请求,否则报错。

预检请求的方式是options,头信息里面关键字段是origin,表示来自哪个源。服务器收到预检请求后检查origin,确认是否允许跨源请求,就可以做出回应了。

允许请求:在http回应中,关键是Access-Control-Allow-Origin字段,如:Access-Control-Allow-Origin:http://api.com,表示http://api.com可以请求数据。设为*,表示同意任何跨域。

不允许请求:会返回一个正常的http回应,但没有任何CORS相关的头信息字段,浏览器会认为不同意预检请求,触发一个错误,被XMLHttpRequest的onerror捕获。

总而言之,普通跨域请求,只要服务端设置Access-Control-Allow-Origin即可,前端无须设置。带cookie请求,需要前后端都设置字段。注意,所带cookie为跨域请求接口所在域的cookie,而非当前页的。

查了一下前端带cookie请求咋实现:

js

 var xhr = new XMLHttpRequest(); // 前端设置是否带cookie
 xhr.withCredentials = true;

jquery

  $.ajax({
    xhrFields: {        
      withCredentials: true // 前端设置是否带cookie    
    },
  });

vue:

vue框架在vue-resource封装的ajax组件中加入以下代码:
Vue.http.options.credentials = true

ok ,总算写完啦~~~

哦,对了,加一下ajax跨域的几种现象(这几种现象这个博客说的很好:http://www.cnblogs.com/dailc/p/5893341.html#crossDomain_crosPrinciple)

时间: 2024-12-25 17:19:08

js跨域的相关文章

谷歌、火狐浏览器下实现JS跨域iframe高度自适应的完美解决方法,跨域调用JS不再是难题!

谷歌.火狐浏览器下实现JS跨域iframe高度自适应的解决方法 导读:今天开发的时候遇到个iframe自适应高度的问题,相信大家对这个不陌生,但是一般我们都是在同一个项目使用iframe嵌套页面,这个ifame高度自适应网上一搜一大把,今天要讲的如何在不同的网站下进行相互的调用跟在同一个网站下是一个效果:例如我在自己的项目里面Iframe  了第一博客的页面  http://www.diyibk.com/   当第一博客的页面高度变化了怎么通知父页面呢? 这个时候在谷歌下肯定是拿不到 ifram

Js 跨域上传文件

代码在github上( https://github.com/andygithubchen/jsUpload ),请结合github上的文件阅读. 主要实现js跨域上传文件,这里的跨域目前只在两个域名所指向的服务器在同一局域网内. 当然,这两种方案都可以做同域名上传. 例如: 192.168.1.60 www.test.cn 192.168.1.61 www.video.cn 如果要在www.test.com域名下上传文件到www.video.com域名下,可以使用下面这两个方案: 方案一(在s

利用JS跨域做一个简单的页面访问统计系统

其实在大部分互联网web产品中,我们通常会用百度统计或者谷歌统计分析系统,通过在程序中引入特定的JS脚本,然后便可以在这些统计系统中看到自己网站页面具体的访问情况.但是有些时候,由于一些特殊情况,我们需要自己来设计统计系统.由于前段时间公司的业务需求,我也是自己尝试了下,本文提供的是一个基本思路,统计系统也比较简单. 几个基本统计需求: 1.统计web每个页面用户访问量 2.统计用户访问者的和IP地址信息 3.页面之间的跳转情况 4.访问高峰时间段 服务器结构: 数据库表设计: 以上只是我简单列

三种方法实现js跨域访问

javascript跨域访问是web开发者经常遇到的问题,什么是跨域,一个域上加载的脚本获取或操作另一个域上的文档属性,下面将列出三种实现javascript跨域方法: 1.基于iframe实现跨域 基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com这种特点,也就是两个页面必须属于一个基础域(例如都是xxx.com,或是xxx.com.cn),使用同一协议(例如都是 http)和同一端口(例如都是80),这样在两个页面中同时添加document.domain,就可以实

js跨域请求方式 ---- JSONP原理解析

这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request 分开说明: 一.JSONP: 直观的理解: 就是在客户端动态注册一个函数 function a(data),然后将函数名传到服务器,服务器返回一个a({/*json*/})到客户端运行,这样就调用客户端的 function a(data),从而

js跨域访问

客户端 HTML 1 <div id="oid"></div> 2 <script type="text/javascript"> 3 //获取货号 4 $.ajax({ 5 6 url: "http://192.168.1.191/H.ashx", 7 type: "GET", 8 dataType: 'jsonp', 9 //jsonp的值自定义,如果使用jsoncallback,那么服

JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作是不同的域. 下表给出了相对 http://store.company.com/dir/page.html 同源检测的结果: 要解决跨域的问题,我们可以使用以下几种方法: 1.通过jsonp跨域[解决ajax跨域] 在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的

问卷项目--js跨域

项目中因为要把问卷投放到第三方,并且对方要收集统计数据,因此在调用对方接口的时候就会存在跨域的问题. 1. 什么叫js跨域 浏览器不允许javascript跨域请求其他域名下的内容.端口号不同,主域相同子域不同,协议不同,不同域名等等情况 下面表格里的a.js是无法获取b.js的内容的. 情况 举例 端口号不同 http://www.baidu.com/a.js   vs.  http://www.baidu.com:8080/b.js 主域相同子域不同 http://www.baidu.com

解决js跨域问题的思路及实践

js跨域问题是比较头疼的问题,因为最近的项目都是基于webview这个组件来写的.我加载本地的html文件,文件中有些连接去请求服务器,这时候就会报错,因为安全服务器拒绝js去请求.还有一种问题就是我自己在本地搭建的web服务器(Tomcat,node.js构建的服务器).去请求另外远程服务器的数据,也会发生上述问题.因此很多时候开发的时候,不好测试.今天碰到了一种好方法.特此记录一下. 首先我搭建了web服务器,tomcat和node.js构建的两种web服务器. 思路就是我们在hosts文件

【JavaScript】JS跨域设置和取Cookie

cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie.你可以使用 JavaScript 来创建和取回 cookie 的值.本文主要JS怎样读取Cookie以及域的设置. AD: 在Javascript脚本里,一个cookie 实际就是一个字符串属性.当你读取cookie的值时,就得到一个字符串,里面当前WEB页使用的所有cookies的名称和值.每个cookie除了 name名称和value值这两个属性以外,还有四个属性.这些属性是: