zoukankan      html  css  js  c++  java
  • 跨域问题--自整理

    题目:下面关于浏览器中使用js跨域获取数据的描述,说法错误的是()
    A:域名、端口相同,协议不同的,属于相同的域
    B:JS可以使用jsonp进行跨域
    C:通过修改document。domain来跨子域
    D:使用window.name来进行跨域
     
    答案:A
     
    以下的同源策略是我自己整理的,不够全面,然后已经发表的博文中有一篇我觉得整理的最好的,地址是 https://segmentfault.com/a/1190000011145364
     
    同源策略同源策略是客户端脚本的重要的安全度量标准。最草出自Netscape navigator2.0,目的是防止某个文档或者脚本从多个不同的源装载。javascript中同源策略对于XHR的一个主要约束,它为通信设置了相同的域,相同的端口,相同的协议”这一限制。除了被认可的跨域解决方案以外,试图访问限制以外的资源,会引发安全错误。
    同源策略/SOP(same origin policy)是一种约定,是浏览器最核心也最基础的安全功能,如果缺少了同源策略,浏览器很容易受到XSS,CSFR等攻击。
     
    同源策略限制:
    1、cookie、localStorage和INdexDB无法读取
    2、DOM和JS对象无法获得
    3、Ajax请求不能发送
     
    跨域解决方案:
    1. jsonp
    2. 图像ping
    3. document.damian + iframe
    4. location.hash + iframe
    5. window.name + iframe
    6. postMessage
    7. CORS(cross-origin resource sharing)
    8. nginx代理跨域
    9. nodejs中间件代理跨域
    10. websocket协议跨域
     
    JSONP(json with padding)
    说明:通过动态script元素,为src属性指定一个跨域URL。(因为<script>元素和<img>元素,都有能力不受限制从其他域加载资源)
    JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般在请求中指定。而数据就是传入回调函数中的json数据。
    function handleResponse(response){
    alert("You're at IP address" + response.ip + ", which is in " + response.city + "," +response.region_name);
    }
    var script = document.createElement("script");
    script.src= "http://freegeoip.net/json/?callback=handleResponse";
    document.body.insertBefore(script,document,body.firstChild);
     
    优点:简单易用。支持在浏览器和服务器之间双向通信。
    缺点:一是jsonp从其他域中加载代码执行。如果其他域不安全,很可能在响应中夹带恶意代码,此时除了放弃JSONP调用之外,没有办法追究。二是要确定JSONP请求是否失败并不容易。HTML5中给script增加了onerror事件处理程序(目前支持的浏览器不多)。可以使用计时器检测在指定时间内是否接受到响应。
     
    CORS(cross-origin Resource sharing,跨源资源共享):跨域解决方案。IE8通过XDomainRequest对象支持CORS,其他浏览器通过XHR对象原生支持CORS。图像Ping和JSONP是另外两种跨域通信的技术。
     
     
    图像PING
    说明:使用<img>元素,因为在任何网页中加载图像时,不用担心跨域不跨域。
    图像ping经常用于跟踪用户点击页面或者动态广告曝光次数。
    动态创建图像,使用它们的onload和onerror事件处理程序来确定是否接到了响应。
    图像ping与服务器进行简单的,单向的跨域通信。请求的数据是通过查询字符串发送的,响应可以是任意内容,但通常是像素图或者204响应。通过图像ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,可以知道响应是什么时候接到的。
    var img = new Image();
    img.onload = img.onerror = function(){
    alert("Done");
    }
    img.src = "http://www.example.com/test?name=Nicholas";
     
    缺点:一只能发送get请求,二是无法访问服务器的响应文本。
     
     
    comet
    说明:Comet是一种更高级的Ajax技术(服务器推送)。ajax是从页面向服务器请求数据,Comet是服务器向页面推送数据。
    Comet有两种实现方式:长轮询和流。
    短轮询是浏览器定时向服务器发送请求,看有没有更新的数据。长轮询是页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到有数据可以发送。发送完数据之后,浏览器关闭连接,随机发起一个新请求。
    HTTP流,不同于轮询,它在页面的整个生命周期内只使用一个HTTP连接。浏览器向服务器发送一个请求,服务器保持连接打开,然后周期性的向浏览器发送数据。
    在Firefox,safari,Opera和chrome中,通过侦听readystatechange事件及检测readystate的值是否为3,就可以利用XHR对象实现HTTP流。在上述浏览器中,随着不断从服务器接受数据,readystate的值会周期性地变为3。readystate为3时,responseText属性中就会保存接收到的所有数据。此时需要比较此前接收到的数据,决定从什么位置开始取得最新的数据。
    function createStreamingClient(url, progress, finished){
    var xhr = new XMLHttpRequest(),
    received = 0;
     
    xhr.open("get", url, true);
    xhr.onreadystatechange = function(){
    var result;
    if(xhr.readystate == 3){
    //只取最新数据,并调整计数器
    result = xhr.responseText.substring(received);
    received += result.length;
     
    //调用progress回调函数
    progress(result);
    }else if(xhr.readystate == 4){
    finished(xhr.responseText);
    }
    };
    xhr.send(null);
    return xhr;
    }
    var client = createStreamingClient("streaming.php" , function(data){
    alert("received" + data);
    },function(data){
    alert("done");
    });
     
    websocket
    wensocket:在一个单独的持久连接上提供全双工、双向通信。使用websocket协议。http服务器无法实现web socket,只有支持这种协议的专门服务器才能正常工作。
     
     
    postMessage
    说明:html5中新增的跨文档消息传递(cross-document messaging),有时候简称为XDM。
    web messaging的核心是postMessage()。想当前页面的<iframe>元素或者由当前页面弹出的窗口。
    postMassage(“消息”,消息接收方来自哪个域的字符串);
    var iframeWindow = document.getElementById("myframe").contentWindow;
    iframeWindow.postMessage("A secret","http://www.wrox.com");
    接受到XDM消息是,会触发window的message事件。这个事件是以异步形式触发,因此从发送消息到接收消息可能要经过一段时间的延迟。事件对象包含三个重要信息:
    1、data postMessage()的第一个参数
    2、origin 发送消息的文档所在的域
    3、source 发送消息的文档的window的代理。代理主要用于发送上一条消息的窗口中调用postMessage()方法。如果发送消息的窗口来自同一个域,那这个对象就是window。
    EventUtil.addHandler(window, "message", function(event){
    if(event.origin == "http://www.wrox.com"){
    processMessage(event.data);//处理接收的数据
     
    event.source.postMessage("received","http://p2p.wrox.com");
    }
    });
    通过内嵌框架加载其他域的内容时,XDM是非常方便的。在混搭(mashup)和社交网络应用中,这种传递消息的方法极为常用。
     
     
     
     
     
     
     
     
  • 相关阅读:
    <mySql完全手册>2011031401
    <海量数据库解决方案>2011030801
    检索
    <mySql完全手册>2011022401
    <自己动手写操作系统>2011031601
    数据结构和算法基础
    <海量数据库解决方案>2011031001
    <自己动手写操作系统>2011032101
    Delphi方法类型
    .NET下的Login机制
  • 原文地址:https://www.cnblogs.com/Jamie1032797633/p/9340914.html
Copyright © 2011-2022 走看看