zoukankan      html  css  js  c++  java
  • JS系列

     

    同源策略:

    浏览器中有个安全机制,就是同源策略,下面介绍同源策略。同源是指同协议同域名同端口,必须三同,缺一不可。

     

     

    限制范围:

    (1) Cookie、LocalStorage 和 IndexDB 无法读取。

    (2) DOM 无法获得。

    (3) AJAX 请求不能发送。

    避免方案:

    1. 设置docnment.domain

    两个网页一级域名相同,二级域名不同,浏览器允许通过设置document.domain共享 Cookie。

    举例:

    A网页是http://w1.example.com/a.html; B网页是http://w2.example.com/b.html

    设置相同的document.domain,两个网页就可以共享Cookie。document.domain = 'example.com';

     

    iframe上使用:

    实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

     

    2. location.hash的iframe跨域

    实现原理:

    a 与 b 跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。具体步骤:

     

    A --> B:

    A页面,有个iframe的B页面,A页面通过选择器获取到B的dom节点,在B的src上添加哈希值;

    B页面通过监听哈希值的变化,获取到A页面传递的数据;

     

    B --> C:

    B页面有个iframe的C页面,地址和A页面同源;

    B页面通过选择器获取到C的dom节点,在C的src上添加哈希值;

    C页面通过监听哈希值的变化,获取到B页面传递的数据;

    C页面和A页面同源,所以能获取A页面的window对象(window.parent.parent),通过传参数调用A页面的方法,间接达到B与A通讯;

     

     

    3.window.name的iframe跨域

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

    1. 父窗口先打开一个子窗口,载入一个不同源的网页,该网页将信息写入window.name属性。window.name = data;

    2. 接着,子窗口跳回一个与主窗口同域的网址。location = 'http://parent.url.com/xxx.html';

    3. 然后,主窗口就可以读取子窗口的window.name了。var data = document.getElementById('myFrame').contentWindow.name;

    这种方法的优点是,window.name容量很大,可以放置非常长的字符串;缺点是必须监听子窗口window.name属性的变化,影响网页性能。

     

    4.postMessage跨域(跨文本档、多窗口、跨域消息传递)

    HTML5引入了一个全新的API:跨文档通信 API(Cross-document messaging)。这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。

     

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

    第一个参数是具体的信息内容,

    第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。

     

     

    父向子发信息:子页面window对象.postMessage(参数, 子页面url)

    var popup = window.open('http://bbb.com', 'title');

    popup.postMessage('Hello World!', 'http://bbb.com');

     

    子向父发信息:父页面window对象.postMessage(参数, 父页面url)

    window.opener.postMessage('Nice to see you', 'http://aaa.com');

     

    父子窗口通过message事件获取信息

    window.addEventListener('message', function(e) {console.log(e.data);},false);

    message事件的事件对象event,提供以下三个属性。

      • event.source:发送消息的窗口
      • event.origin: 消息发向的网址
      • event.data: 消息内容

     

    下面是iframe通过postMessage进行跨域:

     

    5.JSONP

    同源政策规定,AJAX请求只能发给同源的网址,否则就报错。除了架设服务器代理,jsonp规避这个限制。

    优点:jsonp是服务器与客户端跨源通信的常用方法。简单适用,老式浏览器全部支持,服务器改造非常小。

    它的基本思想是,使用<script>标签可以跨域的特点实现,具体步骤如下:

    1. 网页动态插入<script>元素,由它向跨源网址发出请求,请求的查询字符串有一个callback参数,指定回调函数的名字。

    2. 服务器返回 script 标签的内容,内容就是调用指定的回调函数,并且将返回数据以参数的显示传递;

     

    6.CORS

    CORS需要浏览器和服务器同时支持。目前所有浏览器都支持该功能,IE浏览器不能低于IE10;

    浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)

    整个通信过程,都是浏览器自动完成。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。

    浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

     

    简单请求:

    同时满足以下两大条件,就属于简单请求

    1. 请求方法是以下三种方法之一:HEAD、GET、POST

    2. HTTP的头信息不超出以下几种字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

     

    基本流程:

    1.浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段;Origin字段说明本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

    2.如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现回应的头信息没有包含Access-Control-Allow-Origin字段,抛出一个错误,被XMLHttpRequestonerror回调函数捕获(注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200)

    3.在指定范围,服务器返回的响应,会多出几个头信息字段:

    1. Access-Control-Allow-Origin: http://api.bob.com(请求时Origin字段的值或者*,*表示接受任意域名的请求)

    2. Access-Control-Allow-Credentials: true(布尔值,表示是否允许发送Cookie;默认不发送false; 同时开发者必须在AJAX请求中打开withCredentials属性 xhr.withCredentials = true

    3. Access-Control-Expose-Headers: FooBar (XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值)

     

    非简单请求:

    对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json;

     

    基本流程:

    1.会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求;浏览器先询问服务器,当前域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错;("预检"请求用的请求方法是OPTIONS

    2.

    待续。。。。

    参考:http://www.ruanyifeng.com/blog/2016/04/cors.html

     

     

     

     

     

  • 相关阅读:
    HDU
    hdu-1260 tickets
    hdu-1024 Max Sum Plus Plus
    spfa+链式前向星模板
    kafka-伪集群搭建
    elasticsearch-安装-centos7- es7.5 搭建
    elk-安装 通过docker
    kibana-安装-通过docker
    logstash -grok插件语法介绍
    docker 启动redis/nginx
  • 原文地址:https://www.cnblogs.com/vs1435/p/6558525.html
Copyright © 2011-2022 走看看