zoukankan      html  css  js  c++  java
  • 同源与跨域

    同源

    不同源 则跨域

    同源策略的基本概念

    1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。 同源策略:最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。现在浏览器的所谓"同源"指的是"三个相同":

    协议相同
    域名相同
    端口相同

    举例来说,http://www.example.com/dir/page.html这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。

    //http://www.example.com/dir2/other.html:同源
    //http://example.com/dir/other.html:不同源(域名不同)
    //http://v2.www.example.com/dir/other.html:不同源(域名不同)
    //http://www.example.com:81/dir/other.html:不同源(端口不同)

    同源策略的目的

    同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

    同源策略的限制范围

    随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制。

    //1. Cookie、LocalStorage 无法读取。
    //2. DOM 无法获得。
    //3. AJAX 请求不能发送。

    虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域

    跨域

    【演示跨域问题.html】

    jsonp

    JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。原理:服务端返回一个预先定义好的javascript函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合。

    script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有imglink标签

    <!--不受同源策略的标签-->
    <img src="http://www.api.com/1.jpg" alt="">
    <link rel="stylesheet" href="http://www.api.com/1.css">
    <script src="http://www.api.com/1.js"></script>

    jsonp演化过程

    jsonp原理大家知道即可,不用太过于去纠结这个原理,因此jquery已经帮我们封装好了,我们使用起来非常的方便。

    jquery对于jsonp的封装

    //使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。
    $.ajax({
     type:"get",
     url:"http://www.api.com/testjs.php",
     dataType:"jsonp",
     data:{
       uname:"hucc",
       upass:"123456"
    },
     success:function (info) {
       console.log(info);
    }
    });

    【案例:查询天气.html】

    http://lbsyun.baidu.com/index.php?title=car/api/weather

    天气查询api地址

    秘钥:zVo5SStav7IUiVON0kuCogecm87lonOj

    【案例:省市区三级联动.html】

    api地址

    appkey: 3fa977031a30ffe1

    图灵机器人:http://www.tuling123.com/

     

    XMLHttpRequest 2.0

    XMLHttpRequest是一个javascript内置对象,使得Javascript可以进行异步的HTTP通信。2008年2月,就提出了XMLHttpRequest Level 2 草案。

    老版本的XMLHttpRequest的缺点:

    //1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
    //2. 传输数据时,没有进度信息,只能提示完成与否。
    //3. 受到了"同源策略"的限制

     

    新版本的功能:

    //1. 可以设置timeout 超时时间
    //2. 可以使用formData对象管理表单数据
    //3. 可以获取数据传输的进度信息

    注意:我们现在使用new XMLHttpRequest创建的对象就是2.0对象了,我们之前学的是1.0的语法,现在学习一些2.0的新特性即可。

    timeout设置超时

    xhr.timeout = 3000;//设置超时时间
    xhr.ontimeout = function(){
     alert("请求超时");
    }

     

    formData管理表单数据

    formData对象类似于jquery的serialize方法,用于管理表单数据

    //使用特点: 
    //1. 实例化一个formData对象, new formData(form); form就是表单元素
    //4. formData对象可以直接作为 xhr.send(formData)的参数。注意此时数据是以二进制的形式进行传输。
    //5. formData有一个append方法,可以添加参数。formData.append("id", "1111");
    //6. 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。

     

    代码示例:

    //1. 使用formData必须发送post请求
       xhr.open("post", "02-formData.php");
       
    //2. 获取表单元素
    var form = document.querySelector("#myForm");
    //3. 创建form对象,可以直接作为send的参数。
    var formData = new FormData(form);

    //4. formData可以使用append方法添加参数
    formData.append("id", "1111");

    //5. 发送,不需要指定请求头,浏览器会自动选择合适的请求头
    xhr.send(formData);

     

    文件上传

    以前,文件上传需要借助表单进行上传,但是表单上传是同步的,也就是说文件上传时,页面需要提交和刷新,用户体验不友好,xhr2.0中的formData对象支持文件的异步上传。

    var formData = new FormData();
    //获取上传的文件,传递到后端
    var file = document.getElementById("file").files[0];
    formData.append("file", file);
    xhr.send(formData);

     

    显示文件进度信息

    xhr2.0还支持获取上传文件的进度信息,因此我们可以根据进度信息可以实时的显示文件的上传进度。

    1. 需要注册 xhr.upload.onprogress = function(e){} 事件,用于监听文件上传的进度.注意:需要在send之前注册。
    2. 上传的进度信息会存储事件对象e中
    3. e.loaded表示已上传的大小   e.total表示整个文件的大小

     

    代码参考:

    xhr.upload.onprogress = function (e) {
     
     inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
     span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
    }

    xhr.send(formData);

    如果上传文件超过8M,php会报错,需要进行设置,允许php上传大文件。

     

     

    跨域资源共享(CORS)

    cors的使用

    新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称CORS)。

    跨域资源共享(CORS)的前提

    • 浏览器支持这个功能

    • 服务器必须允许这种跨域。

    服务器允许跨域的代码:

    //允许所有的域名访问这个接口
    header("Access-Control-Allow-Origin:*");
    //允许www.study.com这个域名访问这个接口
    header("Access-Control-Allow-Origin:http://www.study.com");

     

    CORS的具体流程(了解)

    1. 浏览器会根据同源策略 查看是否是跨域请求,如果同源,直接发送ajax请求。

    2. 如果非同源,说明是跨域请求,浏览器会自动发送一条请求(预检请求 ),并不会携带数据,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了header('Access-Control-Allow-Origin:请求源域名或者*');

    3. 如果没有设置,说明服务器不允许使用cors跨域,那么浏览器不会发送真正的ajax请求。

    4. 如果返回的响应头中设置了header('Access-Control-Allow-Origin:请求源域名或者*');,浏览器会跟请求头中的Origin: http://www.study.com进行对比,如果满足要求,则发送真正的ajax请求,否则不发送。

    5. 结论:跨域行为是浏览器行为,是浏览器阻止了ajax行为。服务器与服务器之间是不存在跨域的问题的

    【案例:图灵机器人】

    其他的跨域手段(没卵用)

    以下方式基本不用,了解即可:

    1、顶级域名相同的可以通过domain.name来解决,即同时设置 domain.name = 顶级域名(如example.com) 2、document.domain + iframe 3、window.name + iframe 4、location.hash + iframe 5、window.postMessage()

    其他跨域方式

    虚拟主机配置

    在一台web服务器上,我们可以通过配置虚拟主机,然后分别设定根目录,实现对多个网站的管理。

    具体步骤如下:

    1.找到http.conf文件

    找到470行,去掉#号注释

    # Virtual hosts
    Include conf/extra/httpd-vhosts.conf

     

    2.找到httpd-vhosts.conf文件

    在目录:D:phpStudyApacheconfextra下找到httpd-vhosts.conf文件

    # 默认的虚拟主机
    <VirtualHost _default_:80>
    DocumentRoot "C:wwwstudy"
    <Directory "C:wwwstudy">
    Options +Indexes +FollowSymLinks +ExecCGI
    AllowOverride All
    Order allow,deny
    Allow from all
    Require all granted
    </Directory>
    </VirtualHost>
    
    # Add any other Virtual Hosts below
    <VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    #根目录
    DocumentRoot "C:wwwshow"
    #域名
    ServerName show.com
    #完整域名
    ServerAlias www.show.com
    ErrorLog "logs/dummy-host.example.com-error.log"
    CustomLog "logs/dummy-host.example.com-access.log" common
    </VirtualHost>
    懦夫从未启程,弱者死在途中
  • 相关阅读:
    AGC037F Counting of Subarrays
    AGC025F Addition and Andition
    CF506C Mr. Kitayuta vs. Bamboos
    AGC032D Rotation Sort
    ARC101F Robots and Exits
    AGC032E Modulo Pairing
    CF559E Gerald and Path
    CF685C Optimal Point
    聊聊Mysql索引和redis跳表
    什么是线程安全
  • 原文地址:https://www.cnblogs.com/oliviazhang/p/13567968.html
Copyright © 2011-2022 走看看