zoukankan      html  css  js  c++  java
  • 你不知道的html-高级前端课程笔记总结

    第一部分  跨域及其相关知识

      什么是同源策略:指域名、协议、端口均相同,默认端口是80,二级域名也不是同源。

    为了保证用户信息的安全,防止恶意的网站窃取数据。

       浏览器之间不能访问不同域名的cookie,提交表单的时候不受同源策略的限制,所以有跨站脚本攻击

      同源策略的限制对象(跨域)

      1)cookie、localStorage、IndexDB无法读取

      2)DOM无法获取

      3)  AJAX请求不能发送

      跨域的方法:

      1、设置同源策略(hosts)

      test.xxx.com  a.html

      <script>

        document.domain = 'example.com';  //设置同源策略

        document.cookie = 'text1=hello';

      </script>

      test2.xxx.com  b.html

      <script>

        可以取到cookie中的值

      </script>

      后台设置同源   domain = .example.com;

      注意这种方法只适用于cookie和iframe窗口,localStorage和IndexDB无法通过这种方式规避同源政策,而要使用PostMessage API。

      2、iframe通过下面三种方式实现跨域的信息传递

      a)片段识别符,即#号后面的内容,父窗口通过#后面的内容传递给子窗口信息

      父窗口代码:
      var src = originURL + '#' + data;

      document.getElementById('myIFrame').src = src;

      子窗口代码:

      window.onhashchange = checkMessage;

      function checkMessage(){

        var messaage = window.location.hash;

      }

      同样的,子窗口也可以改变父窗口的片段标识符。

      如果只改变片段标识符页面不会刷新。

      b)window.name

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

      这个方法感觉没什么用,要不然就是我没有理解,可以参考原文

    http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

      c)window.postMessage

      跨文档通信API,这个是window对象新增的方法,允许跨窗口通信,无论两个窗口是否同源。

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

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

      postMessage方法的第一个参数是具体的信息内容,第二个参数是接收信息的窗口的源,即‘协议+域名+端口’,也可设为*,表示不限制域名,向所有窗口发送

     event.source:发送消息的窗口

      event.origin:消息发向的网址

      event.data: 消息内容。data的内容最新的浏览器可以接收任何格式的数据 

    window.addEventListener('message', receiveMessage);
    function receiveMessage(event) {
      if (event.origin !== 'http://aaa.com') return;
      if (event.data === 'Hello World') {
          event.source.postMessage('Hello', event.origin);
      } else {
        console.log(event.data);
      }
    }
    window.onmessage = function(e){}
    写法是上面这种形式,源页面打开其他域的页面,然后用获取的窗口变量postMessage,新打开的页面会收到发送的信息。
    参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
    postMessage要注意安全性,一定要指明来源和接收的格式。因为监听方法可以收到任何网页的信息
    还可以通过postMessage来操作localStorage

    加强版的子窗口接收消息的代码如下。

    
    window.onmessage = function(e) {
      if (e.origin !== 'http://bbb.com') return;
      var payload = JSON.parse(e.data);
      switch (payload.method) {
        case 'set':
          localStorage.setItem(payload.key, JSON.stringify(payload.data));
          break;
        case 'get':
          var parent = window.parent;
          var data = localStorage.getItem(payload.key);
          parent.postMessage(data, 'http://aaa.com');
          break;
        case 'remove':
          localStorage.removeItem(payload.key);
          break;
      }
    };
    

    加强版的父窗口发送消息代码如下。

    
    var win = document.getElementsByTagName('iframe')[0].contentWindow;
    var obj = { name: 'Jack' };
    // 存入对象
    win.postMessage(JSON.stringify({key: 'storage', method: 'set', data: obj}), 'http://bbb.com');
    // 读取对象
    win.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");
    window.onmessage = function(e) {
      if (e.origin != 'http://aaa.com') return;
      // "Jack"
      console.log(JSON.parse(e.data).name);
    };
    3、ajax实现跨域(除了可以使用代理服务器,如nginx,proxy)
    a)jsonp(JSON with Padding
    防护垫)
    jsonp的原理是根据script src的跨域特性实现的,需要服务器配合,调用一个callback函数

    首先,网页动态插入<script>元素,由它向跨源网址发出请求。

    
    function addScriptTag(src) {
      var script = document.createElement('script');
      script.setAttribute("type","text/javascript");
      script.src = src;
      document.body.appendChild(script);
    }
    
    window.onload = function () {
      addScriptTag('http://example.com/ip?callback=foo');
    }
    
    function foo(data) {
      console.log('Your public IP address is: ' + data.ip);
    };

    上面代码通过动态添加<script>元素,向服务器example.com发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。

    服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。

    
    foo({
      "ip": "8.8.8.8"
    });
    

    由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。

    b)WebSocket

    WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。发送的头信息中有一个origin,服务器会根据这个源来判断是否是对的客户端。应用场景,数据实时变化的页面,如股票页面,聊天页面等。

    参考文档:https://www.cnblogs.com/wei2yi/archive/2011/03/23/1992830.html

    c)CORS

    CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写,它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。

    它发出的也是XMLHttpRequest请求,它的内部机制是:

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

    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

    因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

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

      

    以上除了CORS是后台跨域设置,其他都是前端跨域,除此之外还有以下方式

      img  link(css 的攻击注入,background请求跨域)

      把代码压缩进图片(canvas)

    小技巧:  

    可以用img来测试网速,并作一些其他的处理,方式就是用

      var img = new img();

      img.src = '';   //1kb的图片

      var start = Date.now();

      img.onload = function(){

        var end = Date.now();

        var t = end - start;

      }

    第二部分   html语义化,常用的语义化结构

    常用的语义化结构:  

      <header>

        <nav></nav>  

      </header>

      <div class="content">

        <section></section>

        <section></section>

        <aside></aside>

        <ul></ul>

        <ol></ol>

        <p></p>

      </div>

      <footer></footer>

      这个目前用的少,语义化知道,但是基本没用,语义化的作用:

      a、去掉或样式丢失的时候能让页面呈现清晰的结构

      b、屏幕阅读器(如果访客有视障碍)完全会根据你的标记来“读”你的网页

      c、PDA、手机等设备可能无法像普通电脑的浏览器一样来渲染网页(通常是因为这些设备对css的支持较弱)

      d、搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重。搜索引擎是很重要的访客。你的页面是否对爬虫容易理解非常重要,因为爬虫很大程度上会忽略用于表现的标记,而只注重语义标记,SEO主要还是靠你网站的内容和外部链接的

      e、便于团队开发和维护,代码可读性较好

      html少写:减少dom渲染的时间,使用::before  ::after,来增加元素

      

      

  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/wenwenli/p/html.html
Copyright © 2011-2022 走看看